WAVExtractor.cpp revision f99f049dd228333e3d6f886efe373f8e461ff2da
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 181f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber if (mBitsPerSample != 8 && mBitsPerSample != 16) { 1820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_UNSUPPORTED; 1830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mValidFormat = true; 1860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } else if (!memcmp(chunkHeader, "data", 4)) { 1870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mValidFormat) { 1880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mDataOffset = offset; 1890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mDataSize = chunkSize; 1900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 191f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mTrackMeta = new MetaData; 192f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mTrackMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 193f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mTrackMeta->setInt32(kKeyChannelCount, mNumChannels); 194f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mTrackMeta->setInt32(kKeySampleRate, mSampleRate); 195f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 196f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber size_t bytesPerSample = mBitsPerSample >> 3; 197f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 198f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber int64_t durationUs = 199f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 1000000LL * (mDataSize / (mNumChannels * bytesPerSample)) 200f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber / mSampleRate; 201f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 202f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mTrackMeta->setInt64(kKeyDuration, durationUs); 203f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 2040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 2050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber offset += chunkSize; 2090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 2120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberconst size_t WAVSource::kMaxFrameSize = 32768; 2150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::WAVSource( 2170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber const sp<DataSource> &dataSource, 218f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber const sp<MetaData> &meta, 219f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber int32_t bitsPerSample, 2200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber off_t offset, size_t size) 2210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber : mDataSource(dataSource), 222f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mMeta(meta), 223f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mSampleRate(0), 224f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mNumChannels(0), 225f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mBitsPerSample(bitsPerSample), 2260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mOffset(offset), 2270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mSize(size), 2280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted(false), 2290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup(NULL) { 230f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber CHECK(mMeta->findInt32(kKeySampleRate, &mSampleRate)); 231f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber CHECK(mMeta->findInt32(kKeyChannelCount, &mNumChannels)); 2320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::~WAVSource() { 2350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mStarted) { 2360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber stop(); 2370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::start(MetaData *params) { 2410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber LOGV("WAVSource::start"); 2420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber CHECK(!mStarted); 2440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup = new MediaBufferGroup; 2460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup->add_buffer(new MediaBuffer(kMaxFrameSize)); 2470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 248f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber if (mBitsPerSample == 8) { 249f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber // As a temporary buffer for 8->16 bit conversion. 250f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mGroup->add_buffer(new MediaBuffer(kMaxFrameSize)); 251f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber } 252f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 2530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos = mOffset; 2540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted = true; 2560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 2580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::stop() { 2610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber LOGV("WAVSource::stop"); 2620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber CHECK(mStarted); 2640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber delete mGroup; 2660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup = NULL; 2670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted = false; 2690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 2710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVSource::getFormat() { 2740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber LOGV("WAVSource::getFormat"); 2750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 276f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber return mMeta; 2770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 2780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::read( 2800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBuffer **out, const ReadOptions *options) { 2810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *out = NULL; 2820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int64_t seekTimeUs; 2840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (options != NULL && options->getSeekTo(&seekTimeUs)) { 2850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int64_t pos = (seekTimeUs * mSampleRate) / 1000000 * mNumChannels * 2; 2860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (pos > mSize) { 2870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber pos = mSize; 2880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos = pos + mOffset; 2900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBuffer *buffer; 2930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber status_t err = mGroup->acquire_buffer(&buffer); 2940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (err != OK) { 2950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return err; 2960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber ssize_t n = mDataSource->readAt( 299f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mCurrentPos, buffer->data(), 300f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mBitsPerSample == 8 ? kMaxFrameSize / 2 : kMaxFrameSize); 3010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (n <= 0) { 3030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->release(); 3040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer = NULL; 3050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_END_OF_STREAM; 3070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos += n; 3100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->set_range(0, n); 312f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 313f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber if (mBitsPerSample == 8) { 314f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber // Convert 8-bit unsigned samples to 16-bit signed. 315f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 316f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber MediaBuffer *tmp; 317f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber CHECK_EQ(mGroup->acquire_buffer(&tmp), OK); 318f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 319f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber // The new buffer holds the sample number of samples, but each 320f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber // one is 2 bytes wide. 321f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber tmp->set_range(0, 2 * n); 322f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 323f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber int16_t *dst = (int16_t *)tmp->data(); 324f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber const uint8_t *src = (const uint8_t *)buffer->data(); 325f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber while (n-- > 0) { 326f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber *dst++ = ((int16_t)(*src) - 128) * 256; 327f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber ++src; 328f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber } 329f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 330f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber buffer->release(); 331f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber buffer = tmp; 332f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber } 333f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 334f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber size_t bytesPerSample = mBitsPerSample >> 3; 335f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 3360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->meta_data()->setInt64( 3370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber kKeyTime, 3380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1000000LL * (mCurrentPos - mOffset) 339f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber / (mNumChannels * bytesPerSample) / mSampleRate); 3400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *out = buffer; 3430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 3450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber//////////////////////////////////////////////////////////////////////////////// 3480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberbool SniffWAV( 3500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 3510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber char header[12]; 3520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) { 3530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return false; 3540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) { 3570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return false; 3580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_WAV; 3610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *confidence = 0.3f; 3620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return true; 3640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} // namespace android 3670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 368