WAVExtractor.cpp revision 984d8f40c15e7fd757a9fdc007aad75549aa0fce
10dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber/* 20dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * Copyright (C) 2009 The Android Open Source Project 30dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * 40dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 50dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * you may not use this file except in compliance with the License. 60dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * You may obtain a copy of the License at 70dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * 80dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 90dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * 100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * Unless required by applicable law or agreed to in writing, software 110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * See the License for the specific language governing permissions and 140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * limitations under the License. 150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber */ 160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber//#define LOG_NDEBUG 0 180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#define LOG_TAG "WAVExtractor" 190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <utils/Log.h> 200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include "include/WAVExtractor.h" 220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/DataSource.h> 240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaDebug.h> 260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaDefs.h> 270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaErrors.h> 280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaSource.h> 290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MetaData.h> 300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <utils/String8.h> 310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubernamespace android { 330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint16_t WAVE_FORMAT_PCM = 1; 350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint32_t U32_LE_AT(const uint8_t *ptr) { 370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0]; 380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint16_t U16_LE_AT(const uint8_t *ptr) { 410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ptr[1] << 8 | ptr[0]; 420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstruct WAVSource : public MediaSource { 450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber WAVSource( 460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber const sp<DataSource> &dataSource, 47f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber const sp<MetaData> &meta, 48f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber int32_t bitsPerSample, 490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber off_t offset, size_t size); 500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual status_t start(MetaData *params = NULL); 520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual status_t stop(); 530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual sp<MetaData> getFormat(); 540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual status_t read( 560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprotected: 590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual ~WAVSource(); 600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprivate: 620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber static const size_t kMaxFrameSize; 630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber sp<DataSource> mDataSource; 65f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber sp<MetaData> mMeta; 660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int32_t mSampleRate; 670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int32_t mNumChannels; 68f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber int32_t mBitsPerSample; 690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber off_t mOffset; 700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t mSize; 710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber bool mStarted; 720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBufferGroup *mGroup; 730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber off_t mCurrentPos; 740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber WAVSource(const WAVSource &); 760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber WAVSource &operator=(const WAVSource &); 770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}; 780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::WAVExtractor(const sp<DataSource> &source) 800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber : mDataSource(source), 810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mValidFormat(false) { 820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mInitCheck = init(); 830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::~WAVExtractor() { 860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 887be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> WAVExtractor::getMetaData() { 897be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber sp<MetaData> meta = new MetaData; 907be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 917be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if (mInitCheck != OK) { 927be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber return meta; 937be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 947be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 957be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber meta->setCString(kKeyMIMEType, "audio/x-wav"); 967be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 977be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber return meta; 987be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 997be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 1000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersize_t WAVExtractor::countTracks() { 1010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return mInitCheck == OK ? 1 : 0; 1020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MediaSource> WAVExtractor::getTrack(size_t index) { 1050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mInitCheck != OK || index > 0) { 1060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NULL; 1070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return new WAVSource( 110f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mDataSource, mTrackMeta, 111f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mBitsPerSample, mDataOffset, mDataSize); 1120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVExtractor::getTrackMetaData( 1150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t index, uint32_t flags) { 1160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mInitCheck != OK || index > 0) { 1170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NULL; 1180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 120f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber return mTrackMeta; 1210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVExtractor::init() { 1240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint8_t header[12]; 1250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mDataSource->readAt( 1260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 0, header, sizeof(header)) < (ssize_t)sizeof(header)) { 1270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) { 1310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t totalSize = U32_LE_AT(&header[4]); 1350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber off_t offset = 12; 1370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t remainingSize = totalSize; 1380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber while (remainingSize >= 8) { 1390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint8_t chunkHeader[8]; 1400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mDataSource->readAt(offset, chunkHeader, 8) < 8) { 1410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber remainingSize -= 8; 1450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber offset += 8; 146f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 1470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint32_t chunkSize = U32_LE_AT(&chunkHeader[4]); 1480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (chunkSize > remainingSize) { 1500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (!memcmp(chunkHeader, "fmt ", 4)) { 1540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (chunkSize < 16) { 1550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint8_t formatSpec[16]; 1590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mDataSource->readAt(offset, formatSpec, 16) < 16) { 1600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint16_t format = U16_LE_AT(formatSpec); 1640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (format != WAVE_FORMAT_PCM) { 1650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_UNSUPPORTED; 1660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mNumChannels = U16_LE_AT(&formatSpec[2]); 1690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mNumChannels != 1 && mNumChannels != 2) { 1700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_UNSUPPORTED; 1710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mSampleRate = U32_LE_AT(&formatSpec[4]); 1740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 175f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber if (mSampleRate == 0) { 176f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber return ERROR_MALFORMED; 177f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber } 178f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 179f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mBitsPerSample = U16_LE_AT(&formatSpec[14]); 180f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 181984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber if (mBitsPerSample != 8 && mBitsPerSample != 16 182984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber && mBitsPerSample != 24) { 1830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_UNSUPPORTED; 1840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mValidFormat = true; 1870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } else if (!memcmp(chunkHeader, "data", 4)) { 1880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mValidFormat) { 1890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mDataOffset = offset; 1900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mDataSize = chunkSize; 1910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 192f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mTrackMeta = new MetaData; 193f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mTrackMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 194f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mTrackMeta->setInt32(kKeyChannelCount, mNumChannels); 195f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mTrackMeta->setInt32(kKeySampleRate, mSampleRate); 196f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 197f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber size_t bytesPerSample = mBitsPerSample >> 3; 198f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 199f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber int64_t durationUs = 200f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 1000000LL * (mDataSize / (mNumChannels * bytesPerSample)) 201f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber / mSampleRate; 202f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 203f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mTrackMeta->setInt64(kKeyDuration, durationUs); 204f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 2050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 2060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber offset += chunkSize; 2100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 2130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberconst size_t WAVSource::kMaxFrameSize = 32768; 2160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::WAVSource( 2180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber const sp<DataSource> &dataSource, 219f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber const sp<MetaData> &meta, 220f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber int32_t bitsPerSample, 2210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber off_t offset, size_t size) 2220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber : mDataSource(dataSource), 223f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mMeta(meta), 224f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mSampleRate(0), 225f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mNumChannels(0), 226f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mBitsPerSample(bitsPerSample), 2270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mOffset(offset), 2280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mSize(size), 2290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted(false), 2300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup(NULL) { 231f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber CHECK(mMeta->findInt32(kKeySampleRate, &mSampleRate)); 232f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber CHECK(mMeta->findInt32(kKeyChannelCount, &mNumChannels)); 2330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::~WAVSource() { 2360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mStarted) { 2370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber stop(); 2380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::start(MetaData *params) { 2420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber LOGV("WAVSource::start"); 2430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber CHECK(!mStarted); 2450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup = new MediaBufferGroup; 2470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup->add_buffer(new MediaBuffer(kMaxFrameSize)); 2480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 249f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber if (mBitsPerSample == 8) { 250f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber // As a temporary buffer for 8->16 bit conversion. 251f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mGroup->add_buffer(new MediaBuffer(kMaxFrameSize)); 252f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber } 253f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 2540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos = mOffset; 2550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted = true; 2570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 2590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::stop() { 2620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber LOGV("WAVSource::stop"); 2630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber CHECK(mStarted); 2650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber delete mGroup; 2670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup = NULL; 2680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted = false; 2700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 2720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVSource::getFormat() { 2750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber LOGV("WAVSource::getFormat"); 2760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 277f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber return mMeta; 2780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::read( 2810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBuffer **out, const ReadOptions *options) { 2820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *out = NULL; 2830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int64_t seekTimeUs; 2850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (options != NULL && options->getSeekTo(&seekTimeUs)) { 2860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int64_t pos = (seekTimeUs * mSampleRate) / 1000000 * mNumChannels * 2; 2870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (pos > mSize) { 2880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber pos = mSize; 2890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos = pos + mOffset; 2910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBuffer *buffer; 2940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber status_t err = mGroup->acquire_buffer(&buffer); 2950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (err != OK) { 2960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return err; 2970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber ssize_t n = mDataSource->readAt( 300f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mCurrentPos, buffer->data(), 301f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mBitsPerSample == 8 ? kMaxFrameSize / 2 : kMaxFrameSize); 3020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (n <= 0) { 3040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->release(); 3050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer = NULL; 3060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_END_OF_STREAM; 3080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos += n; 3110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->set_range(0, n); 313f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 314f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber if (mBitsPerSample == 8) { 315f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber // Convert 8-bit unsigned samples to 16-bit signed. 316f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 317f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber MediaBuffer *tmp; 318f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber CHECK_EQ(mGroup->acquire_buffer(&tmp), OK); 319f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 320f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber // The new buffer holds the sample number of samples, but each 321f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber // one is 2 bytes wide. 322f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber tmp->set_range(0, 2 * n); 323f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 324f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber int16_t *dst = (int16_t *)tmp->data(); 325f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber const uint8_t *src = (const uint8_t *)buffer->data(); 326f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber while (n-- > 0) { 327f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber *dst++ = ((int16_t)(*src) - 128) * 256; 328f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber ++src; 329f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber } 330f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 331f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber buffer->release(); 332f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber buffer = tmp; 333984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber } else if (mBitsPerSample == 24) { 334984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber // Convert 24-bit signed samples to 16-bit signed. 335984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber 336984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber const uint8_t *src = 337984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber (const uint8_t *)buffer->data() + buffer->range_offset(); 338984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber int16_t *dst = (int16_t *)src; 339984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber 340984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber size_t numSamples = buffer->range_length() / 3; 341984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber for (size_t i = 0; i < numSamples; ++i) { 342984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber int32_t x = (int32_t)(src[0] | src[1] << 8 | src[2] << 16); 343984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber x = (x << 8) >> 8; // sign extension 344984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber 345984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber x = x >> 8; 346984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber *dst++ = (int16_t)x; 347984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber src += 3; 348984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber } 349984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber 350984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber buffer->set_range(buffer->range_offset(), 2 * numSamples); 351f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber } 352f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 353f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber size_t bytesPerSample = mBitsPerSample >> 3; 354f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 3550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->meta_data()->setInt64( 3560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber kKeyTime, 3570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1000000LL * (mCurrentPos - mOffset) 358f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber / (mNumChannels * bytesPerSample) / mSampleRate); 3590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *out = buffer; 3620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 3640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber//////////////////////////////////////////////////////////////////////////////// 3670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberbool SniffWAV( 3690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 3700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber char header[12]; 3710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) { 3720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return false; 3730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) { 3760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return false; 3770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_WAV; 3800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *confidence = 0.3f; 3810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return true; 3830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} // namespace android 3860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 387