WAVExtractor.cpp revision 06f6ae34c735640dccdaca6ab1567d8afc9d3938
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 23f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/DataSource.h> 250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaBufferGroup.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> 313bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi#include <cutils/bitops.h> 323bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 333bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi#define CHANNEL_MASK_USE_CHANNEL_ORDER 0 340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubernamespace android { 360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huberenum { 383bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi WAVE_FORMAT_PCM = 0x0001, 393bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi WAVE_FORMAT_ALAW = 0x0006, 403bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi WAVE_FORMAT_MULAW = 0x0007, 413bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi WAVE_FORMAT_EXTENSIBLE = 0xFFFE 4242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber}; 430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 443bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivistatic const char* WAVEEXT_SUBFORMAT = "\x00\x00\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71"; 453bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 463bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint32_t U32_LE_AT(const uint8_t *ptr) { 480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0]; 490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint16_t U16_LE_AT(const uint8_t *ptr) { 520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ptr[1] << 8 | ptr[0]; 530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstruct WAVSource : public MediaSource { 560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber WAVSource( 570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber const sp<DataSource> &dataSource, 58f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber const sp<MetaData> &meta, 5942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber uint16_t waveFormat, 60f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber int32_t bitsPerSample, 61c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset, size_t size); 620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual status_t start(MetaData *params = NULL); 640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual status_t stop(); 650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual sp<MetaData> getFormat(); 660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual status_t read( 680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprotected: 710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual ~WAVSource(); 720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprivate: 740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber static const size_t kMaxFrameSize; 750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber sp<DataSource> mDataSource; 77f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber sp<MetaData> mMeta; 7842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber uint16_t mWaveFormat; 790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int32_t mSampleRate; 800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int32_t mNumChannels; 81f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber int32_t mBitsPerSample; 82c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t mOffset; 830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t mSize; 840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber bool mStarted; 850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBufferGroup *mGroup; 86c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t mCurrentPos; 870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber WAVSource(const WAVSource &); 890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber WAVSource &operator=(const WAVSource &); 900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}; 910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::WAVExtractor(const sp<DataSource> &source) 930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber : mDataSource(source), 943bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi mValidFormat(false), 953bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi mChannelMask(CHANNEL_MASK_USE_CHANNEL_ORDER) { 960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mInitCheck = init(); 970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::~WAVExtractor() { 1000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1027be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> WAVExtractor::getMetaData() { 1037be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber sp<MetaData> meta = new MetaData; 1047be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 1057be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if (mInitCheck != OK) { 1067be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber return meta; 1077be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 1087be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 1097be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber meta->setCString(kKeyMIMEType, "audio/x-wav"); 1107be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 1117be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber return meta; 1127be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 1137be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 1140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersize_t WAVExtractor::countTracks() { 1150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return mInitCheck == OK ? 1 : 0; 1160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MediaSource> WAVExtractor::getTrack(size_t index) { 1190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mInitCheck != OK || index > 0) { 1200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NULL; 1210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return new WAVSource( 124f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mDataSource, mTrackMeta, 12542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber mWaveFormat, mBitsPerSample, mDataOffset, mDataSize); 1260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVExtractor::getTrackMetaData( 1290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t index, uint32_t flags) { 1300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mInitCheck != OK || index > 0) { 1310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NULL; 1320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 134f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber return mTrackMeta; 1350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVExtractor::init() { 1380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint8_t header[12]; 1390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mDataSource->readAt( 1400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 0, header, sizeof(header)) < (ssize_t)sizeof(header)) { 1410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) { 1450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t totalSize = U32_LE_AT(&header[4]); 1490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 150c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset = 12; 1510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t remainingSize = totalSize; 1520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber while (remainingSize >= 8) { 1530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint8_t chunkHeader[8]; 1540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mDataSource->readAt(offset, chunkHeader, 8) < 8) { 1550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber remainingSize -= 8; 1590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber offset += 8; 160f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 1610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint32_t chunkSize = U32_LE_AT(&chunkHeader[4]); 1620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (chunkSize > remainingSize) { 1640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (!memcmp(chunkHeader, "fmt ", 4)) { 1680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (chunkSize < 16) { 1690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1723bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi uint8_t formatSpec[40]; 1733bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mDataSource->readAt(offset, formatSpec, 2) < 2) { 1740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 17742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber mWaveFormat = U16_LE_AT(formatSpec); 17842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber if (mWaveFormat != WAVE_FORMAT_PCM 17942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber && mWaveFormat != WAVE_FORMAT_ALAW 1803bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi && mWaveFormat != WAVE_FORMAT_MULAW 1813bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi && mWaveFormat != WAVE_FORMAT_EXTENSIBLE) { 1820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_UNSUPPORTED; 1830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1853bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi uint8_t fmtSize = 16; 1863bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mWaveFormat == WAVE_FORMAT_EXTENSIBLE) { 1873bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi fmtSize = 40; 1883bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 1893bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mDataSource->readAt(offset, formatSpec, fmtSize) < fmtSize) { 1903bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi return NO_INIT; 1913bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 1923bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 1930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mNumChannels = U16_LE_AT(&formatSpec[2]); 1943bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mWaveFormat != WAVE_FORMAT_EXTENSIBLE) { 1953bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mNumChannels != 1 && mNumChannels != 2) { 1963bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi ALOGW("More than 2 channels (%d) in non-WAVE_EXT, unknown channel mask", 1973bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi mNumChannels); 1983bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 1993bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } else { 2003bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mNumChannels < 1 && mNumChannels > 8) { 2013bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi return ERROR_UNSUPPORTED; 2023bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mSampleRate = U32_LE_AT(&formatSpec[4]); 2060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 207f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber if (mSampleRate == 0) { 208f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber return ERROR_MALFORMED; 209f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber } 210f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 211f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mBitsPerSample = U16_LE_AT(&formatSpec[14]); 212f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 2133bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mWaveFormat == WAVE_FORMAT_PCM 2143bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi || mWaveFormat == WAVE_FORMAT_EXTENSIBLE) { 21542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber if (mBitsPerSample != 8 && mBitsPerSample != 16 21642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber && mBitsPerSample != 24) { 21742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber return ERROR_UNSUPPORTED; 21842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber } 21942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber } else { 22042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber CHECK(mWaveFormat == WAVE_FORMAT_MULAW 22142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber || mWaveFormat == WAVE_FORMAT_ALAW); 22242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber if (mBitsPerSample != 8) { 22342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber return ERROR_UNSUPPORTED; 22442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber } 2250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2273bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mWaveFormat == WAVE_FORMAT_EXTENSIBLE) { 2283bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi uint16_t validBitsPerSample = U16_LE_AT(&formatSpec[18]); 2293bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (validBitsPerSample != mBitsPerSample) { 23006f6ae34c735640dccdaca6ab1567d8afc9d3938Jean-Michel Trivi if (validBitsPerSample != 0) { 23172b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi ALOGE("validBits(%d) != bitsPerSample(%d) are not supported", 23272b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi validBitsPerSample, mBitsPerSample); 23372b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi return ERROR_UNSUPPORTED; 23472b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi } else { 23572b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi // we only support valitBitsPerSample == bitsPerSample but some WAV_EXT 23672b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi // writers don't correctly set the valid bits value, and leave it at 0. 23772b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi ALOGW("WAVE_EXT has 0 valid bits per sample, ignoring"); 23872b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi } 2393bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2403bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 2413bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi mChannelMask = U32_LE_AT(&formatSpec[20]); 2423bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi ALOGV("numChannels=%d channelMask=0x%x", mNumChannels, mChannelMask); 2433bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if ((mChannelMask >> 18) != 0) { 2443bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi ALOGE("invalid channel mask 0x%x", mChannelMask); 2453bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi return ERROR_MALFORMED; 2463bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2473bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 2483bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if ((mChannelMask != CHANNEL_MASK_USE_CHANNEL_ORDER) 2493bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi && (popcount(mChannelMask) != mNumChannels)) { 2503bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi ALOGE("invalid number of channels (%d) in channel mask (0x%x)", 2513bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi popcount(mChannelMask), mChannelMask); 2523bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi return ERROR_MALFORMED; 2533bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2543bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 2553bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi // In a WAVE_EXT header, the first two bytes of the GUID stored at byte 24 contain 2563bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi // the sample format, using the same definitions as a regular WAV header 2573bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi mWaveFormat = U16_LE_AT(&formatSpec[24]); 2583bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mWaveFormat != WAVE_FORMAT_PCM 2593bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi && mWaveFormat != WAVE_FORMAT_ALAW 2603bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi && mWaveFormat != WAVE_FORMAT_MULAW) { 2613bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi return ERROR_UNSUPPORTED; 2623bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2633bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (memcmp(&formatSpec[26], WAVEEXT_SUBFORMAT, 14)) { 2643bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi ALOGE("unsupported GUID"); 2653bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi return ERROR_UNSUPPORTED; 2663bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2673bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2683bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 2690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mValidFormat = true; 2700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } else if (!memcmp(chunkHeader, "data", 4)) { 2710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mValidFormat) { 2720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mDataOffset = offset; 2730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mDataSize = chunkSize; 2740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 275f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mTrackMeta = new MetaData; 27642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber 27742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber switch (mWaveFormat) { 27842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber case WAVE_FORMAT_PCM: 27942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber mTrackMeta->setCString( 28042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 28142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber break; 28242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber case WAVE_FORMAT_ALAW: 28342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber mTrackMeta->setCString( 28442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_ALAW); 28542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber break; 28642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber default: 287f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK_EQ(mWaveFormat, (uint16_t)WAVE_FORMAT_MULAW); 28842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber mTrackMeta->setCString( 28942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_MLAW); 29042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber break; 29142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber } 29242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber 293f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mTrackMeta->setInt32(kKeyChannelCount, mNumChannels); 2943bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi mTrackMeta->setInt32(kKeyChannelMask, mChannelMask); 295f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mTrackMeta->setInt32(kKeySampleRate, mSampleRate); 296f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 297f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber size_t bytesPerSample = mBitsPerSample >> 3; 298f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 299f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber int64_t durationUs = 300f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 1000000LL * (mDataSize / (mNumChannels * bytesPerSample)) 301f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber / mSampleRate; 302f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 303f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mTrackMeta->setInt64(kKeyDuration, durationUs); 304f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 3050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 3060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber offset += chunkSize; 3100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 3130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberconst size_t WAVSource::kMaxFrameSize = 32768; 3160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::WAVSource( 3180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber const sp<DataSource> &dataSource, 319f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber const sp<MetaData> &meta, 32042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber uint16_t waveFormat, 321f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber int32_t bitsPerSample, 322c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset, size_t size) 3230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber : mDataSource(dataSource), 324f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mMeta(meta), 32542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber mWaveFormat(waveFormat), 326f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mSampleRate(0), 327f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mNumChannels(0), 328f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mBitsPerSample(bitsPerSample), 3290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mOffset(offset), 3300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mSize(size), 3310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted(false), 3320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup(NULL) { 333f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber CHECK(mMeta->findInt32(kKeySampleRate, &mSampleRate)); 334f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber CHECK(mMeta->findInt32(kKeyChannelCount, &mNumChannels)); 335bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 336bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mMeta->setInt32(kKeyMaxInputSize, kMaxFrameSize); 3370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::~WAVSource() { 3400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mStarted) { 3410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber stop(); 3420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::start(MetaData *params) { 3463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("WAVSource::start"); 3470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber CHECK(!mStarted); 3490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup = new MediaBufferGroup; 3510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup->add_buffer(new MediaBuffer(kMaxFrameSize)); 3520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 353f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber if (mBitsPerSample == 8) { 354f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber // As a temporary buffer for 8->16 bit conversion. 355f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mGroup->add_buffer(new MediaBuffer(kMaxFrameSize)); 356f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber } 357f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 3580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos = mOffset; 3590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted = true; 3610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 3630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::stop() { 3663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("WAVSource::stop"); 3670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber CHECK(mStarted); 3690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber delete mGroup; 3710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup = NULL; 3720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted = false; 3740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 3760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVSource::getFormat() { 3793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("WAVSource::getFormat"); 3800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 381f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber return mMeta; 3820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::read( 3850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBuffer **out, const ReadOptions *options) { 3860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *out = NULL; 3870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int64_t seekTimeUs; 389abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 390abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) { 39136fb2077764093a0a19ed65770078b9987bd82b1James Dong int64_t pos = (seekTimeUs * mSampleRate) / 1000000 * mNumChannels * (mBitsPerSample >> 3); 3920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (pos > mSize) { 3930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber pos = mSize; 3940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos = pos + mOffset; 3960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBuffer *buffer; 3990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber status_t err = mGroup->acquire_buffer(&buffer); 4000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (err != OK) { 4010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return err; 4020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 4030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 404104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber size_t maxBytesToRead = 405104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber mBitsPerSample == 8 ? kMaxFrameSize / 2 : kMaxFrameSize; 406104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber 407104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber size_t maxBytesAvailable = 408c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong (mCurrentPos - mOffset >= (off64_t)mSize) 409104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber ? 0 : mSize - (mCurrentPos - mOffset); 410104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber 411104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber if (maxBytesToRead > maxBytesAvailable) { 412104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber maxBytesToRead = maxBytesAvailable; 413104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber } 414104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber 4150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber ssize_t n = mDataSource->readAt( 416f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mCurrentPos, buffer->data(), 417104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber maxBytesToRead); 4180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (n <= 0) { 4200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->release(); 4210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer = NULL; 4220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_END_OF_STREAM; 4240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 4250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->set_range(0, n); 427f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 42842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber if (mWaveFormat == WAVE_FORMAT_PCM) { 42942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber if (mBitsPerSample == 8) { 43042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber // Convert 8-bit unsigned samples to 16-bit signed. 431f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 43242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber MediaBuffer *tmp; 433f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK_EQ(mGroup->acquire_buffer(&tmp), (status_t)OK); 434f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 43542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber // The new buffer holds the sample number of samples, but each 43642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber // one is 2 bytes wide. 43742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber tmp->set_range(0, 2 * n); 438f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 43942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber int16_t *dst = (int16_t *)tmp->data(); 44042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber const uint8_t *src = (const uint8_t *)buffer->data(); 4410b3f21761eae9b7d230ddd9b4be76ef02d4cec15Gloria Wang ssize_t numBytes = n; 4420b3f21761eae9b7d230ddd9b4be76ef02d4cec15Gloria Wang 4430b3f21761eae9b7d230ddd9b4be76ef02d4cec15Gloria Wang while (numBytes-- > 0) { 44442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber *dst++ = ((int16_t)(*src) - 128) * 256; 44542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber ++src; 44642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber } 447f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 44842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber buffer->release(); 44942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber buffer = tmp; 45042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber } else if (mBitsPerSample == 24) { 45142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber // Convert 24-bit signed samples to 16-bit signed. 45242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber 45342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber const uint8_t *src = 45442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber (const uint8_t *)buffer->data() + buffer->range_offset(); 45542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber int16_t *dst = (int16_t *)src; 45642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber 45742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber size_t numSamples = buffer->range_length() / 3; 45842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber for (size_t i = 0; i < numSamples; ++i) { 45942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber int32_t x = (int32_t)(src[0] | src[1] << 8 | src[2] << 16); 46042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber x = (x << 8) >> 8; // sign extension 461984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber 46242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber x = x >> 8; 46342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber *dst++ = (int16_t)x; 46442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber src += 3; 46542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber } 46642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber 46742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber buffer->set_range(buffer->range_offset(), 2 * numSamples); 46842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber } 469f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber } 470f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 471f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber size_t bytesPerSample = mBitsPerSample >> 3; 472f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 4730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->meta_data()->setInt64( 4740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber kKeyTime, 4750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1000000LL * (mCurrentPos - mOffset) 476f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber / (mNumChannels * bytesPerSample) / mSampleRate); 4770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4788bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 479f1e10e8ed74cac805d601139882378a1f450fe94James Dong mCurrentPos += n; 4800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *out = buffer; 4820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 4840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 4850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber//////////////////////////////////////////////////////////////////////////////// 4870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberbool SniffWAV( 4895a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 4905a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber sp<AMessage> *) { 4910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber char header[12]; 4920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) { 4930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return false; 4940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 4950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) { 4970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return false; 4980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 4990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 50070d3e260edcd42972864bf501337f0b1a187657dJames Dong sp<MediaExtractor> extractor = new WAVExtractor(source); 50170d3e260edcd42972864bf501337f0b1a187657dJames Dong if (extractor->countTracks() == 0) { 50270d3e260edcd42972864bf501337f0b1a187657dJames Dong return false; 50370d3e260edcd42972864bf501337f0b1a187657dJames Dong } 50470d3e260edcd42972864bf501337f0b1a187657dJames Dong 5050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_WAV; 5060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *confidence = 0.3f; 5070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 5080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return true; 5090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 5100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 5110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} // namespace android 5120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 513