WAVExtractor.cpp revision 75e6e22434d6fb3021738dcef644109374e75643
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 2375e6e22434d6fb3021738dcef644109374e75643Andy Hung#include <audio_utils/primitives.h> 24f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/DataSource.h> 260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaDefs.h> 280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaErrors.h> 290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaSource.h> 300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MetaData.h> 310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <utils/String8.h> 323bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi#include <cutils/bitops.h> 333bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 343bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi#define CHANNEL_MASK_USE_CHANNEL_ORDER 0 350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubernamespace android { 370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huberenum { 393bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi WAVE_FORMAT_PCM = 0x0001, 4075e6e22434d6fb3021738dcef644109374e75643Andy Hung WAVE_FORMAT_IEEE_FLOAT = 0x0003, 413bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi WAVE_FORMAT_ALAW = 0x0006, 423bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi WAVE_FORMAT_MULAW = 0x0007, 43ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen WAVE_FORMAT_MSGSM = 0x0031, 443bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi WAVE_FORMAT_EXTENSIBLE = 0xFFFE 4542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber}; 460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 473bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivistatic const char* WAVEEXT_SUBFORMAT = "\x00\x00\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71"; 483bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 493bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint32_t U32_LE_AT(const uint8_t *ptr) { 510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0]; 520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint16_t U16_LE_AT(const uint8_t *ptr) { 550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ptr[1] << 8 | ptr[0]; 560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstruct WAVSource : public MediaSource { 590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber WAVSource( 600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber const sp<DataSource> &dataSource, 61f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber const sp<MetaData> &meta, 6242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber uint16_t waveFormat, 63f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber int32_t bitsPerSample, 64c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset, size_t size); 650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual status_t start(MetaData *params = NULL); 670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual status_t stop(); 680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual sp<MetaData> getFormat(); 690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual status_t read( 710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprotected: 740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual ~WAVSource(); 750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprivate: 770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber static const size_t kMaxFrameSize; 780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber sp<DataSource> mDataSource; 80f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber sp<MetaData> mMeta; 8142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber uint16_t mWaveFormat; 820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int32_t mSampleRate; 830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int32_t mNumChannels; 84f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber int32_t mBitsPerSample; 85c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t mOffset; 860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t mSize; 870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber bool mStarted; 880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBufferGroup *mGroup; 89c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t mCurrentPos; 900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber WAVSource(const WAVSource &); 920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber WAVSource &operator=(const WAVSource &); 930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}; 940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::WAVExtractor(const sp<DataSource> &source) 960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber : mDataSource(source), 973bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi mValidFormat(false), 983bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi mChannelMask(CHANNEL_MASK_USE_CHANNEL_ORDER) { 990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mInitCheck = init(); 1000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::~WAVExtractor() { 1030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1057be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> WAVExtractor::getMetaData() { 1067be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber sp<MetaData> meta = new MetaData; 1077be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 1087be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if (mInitCheck != OK) { 1097be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber return meta; 1107be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 1117be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 11206096f955d486e229e19956052925f43f2f3f7c4Dongwon Kang meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_WAV); 1137be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 1147be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber return meta; 1157be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 1167be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 1170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersize_t WAVExtractor::countTracks() { 1180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return mInitCheck == OK ? 1 : 0; 1190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 121b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissensp<IMediaSource> WAVExtractor::getTrack(size_t index) { 1220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mInitCheck != OK || index > 0) { 1230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NULL; 1240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return new WAVSource( 127f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mDataSource, mTrackMeta, 12842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber mWaveFormat, mBitsPerSample, mDataOffset, mDataSize); 1290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVExtractor::getTrackMetaData( 13284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber size_t index, uint32_t /* flags */) { 1330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mInitCheck != OK || index > 0) { 1340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NULL; 1350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 137f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber return mTrackMeta; 1380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVExtractor::init() { 1410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint8_t header[12]; 1420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mDataSource->readAt( 1430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 0, header, sizeof(header)) < (ssize_t)sizeof(header)) { 1440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) { 1480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t totalSize = U32_LE_AT(&header[4]); 1520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 153c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset = 12; 1540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t remainingSize = totalSize; 1550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber while (remainingSize >= 8) { 1560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint8_t chunkHeader[8]; 1570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mDataSource->readAt(offset, chunkHeader, 8) < 8) { 1580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber remainingSize -= 8; 1620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber offset += 8; 163f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 1640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint32_t chunkSize = U32_LE_AT(&chunkHeader[4]); 1650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (chunkSize > remainingSize) { 1670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (!memcmp(chunkHeader, "fmt ", 4)) { 1710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (chunkSize < 16) { 1720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1753bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi uint8_t formatSpec[40]; 1763bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mDataSource->readAt(offset, formatSpec, 2) < 2) { 1770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 18042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber mWaveFormat = U16_LE_AT(formatSpec); 18142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber if (mWaveFormat != WAVE_FORMAT_PCM 18275e6e22434d6fb3021738dcef644109374e75643Andy Hung && mWaveFormat != WAVE_FORMAT_IEEE_FLOAT 18342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber && mWaveFormat != WAVE_FORMAT_ALAW 1843bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi && mWaveFormat != WAVE_FORMAT_MULAW 185ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen && mWaveFormat != WAVE_FORMAT_MSGSM 1863bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi && mWaveFormat != WAVE_FORMAT_EXTENSIBLE) { 1870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_UNSUPPORTED; 1880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1903bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi uint8_t fmtSize = 16; 1913bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mWaveFormat == WAVE_FORMAT_EXTENSIBLE) { 1923bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi fmtSize = 40; 1933bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 1943bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mDataSource->readAt(offset, formatSpec, fmtSize) < fmtSize) { 1953bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi return NO_INIT; 1963bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 1973bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 1980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mNumChannels = U16_LE_AT(&formatSpec[2]); 199778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz 200778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz if (mNumChannels < 1 || mNumChannels > 8) { 201778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz ALOGE("Unsupported number of channels (%d)", mNumChannels); 202778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz return ERROR_UNSUPPORTED; 203778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz } 204778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz 2053bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mWaveFormat != WAVE_FORMAT_EXTENSIBLE) { 206778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz if (mNumChannels != 1 && mNumChannels != 2) { 2073bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi ALOGW("More than 2 channels (%d) in non-WAVE_EXT, unknown channel mask", 2083bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi mNumChannels); 2093bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mSampleRate = U32_LE_AT(&formatSpec[4]); 2130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 214f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber if (mSampleRate == 0) { 215f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber return ERROR_MALFORMED; 216f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber } 217f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 218f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mBitsPerSample = U16_LE_AT(&formatSpec[14]); 219f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 2203bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mWaveFormat == WAVE_FORMAT_EXTENSIBLE) { 2213bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi uint16_t validBitsPerSample = U16_LE_AT(&formatSpec[18]); 2223bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (validBitsPerSample != mBitsPerSample) { 22306f6ae34c735640dccdaca6ab1567d8afc9d3938Jean-Michel Trivi if (validBitsPerSample != 0) { 22472b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi ALOGE("validBits(%d) != bitsPerSample(%d) are not supported", 22572b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi validBitsPerSample, mBitsPerSample); 22672b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi return ERROR_UNSUPPORTED; 22772b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi } else { 22872b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi // we only support valitBitsPerSample == bitsPerSample but some WAV_EXT 22972b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi // writers don't correctly set the valid bits value, and leave it at 0. 23072b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi ALOGW("WAVE_EXT has 0 valid bits per sample, ignoring"); 23172b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi } 2323bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2333bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 2343bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi mChannelMask = U32_LE_AT(&formatSpec[20]); 2353bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi ALOGV("numChannels=%d channelMask=0x%x", mNumChannels, mChannelMask); 2363bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if ((mChannelMask >> 18) != 0) { 2373bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi ALOGE("invalid channel mask 0x%x", mChannelMask); 2383bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi return ERROR_MALFORMED; 2393bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2403bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 2413bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if ((mChannelMask != CHANNEL_MASK_USE_CHANNEL_ORDER) 2423bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi && (popcount(mChannelMask) != mNumChannels)) { 2433bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi ALOGE("invalid number of channels (%d) in channel mask (0x%x)", 2443bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi popcount(mChannelMask), mChannelMask); 2453bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi return ERROR_MALFORMED; 2463bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2473bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 2483bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi // In a WAVE_EXT header, the first two bytes of the GUID stored at byte 24 contain 2493bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi // the sample format, using the same definitions as a regular WAV header 2503bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi mWaveFormat = U16_LE_AT(&formatSpec[24]); 2513bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (memcmp(&formatSpec[26], WAVEEXT_SUBFORMAT, 14)) { 2523bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi ALOGE("unsupported GUID"); 2533bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi return ERROR_UNSUPPORTED; 2543bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2553bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2563bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 25775e6e22434d6fb3021738dcef644109374e75643Andy Hung if (mWaveFormat == WAVE_FORMAT_PCM) { 25875e6e22434d6fb3021738dcef644109374e75643Andy Hung if (mBitsPerSample != 8 && mBitsPerSample != 16 25975e6e22434d6fb3021738dcef644109374e75643Andy Hung && mBitsPerSample != 24 && mBitsPerSample != 32) { 26075e6e22434d6fb3021738dcef644109374e75643Andy Hung return ERROR_UNSUPPORTED; 26175e6e22434d6fb3021738dcef644109374e75643Andy Hung } 26275e6e22434d6fb3021738dcef644109374e75643Andy Hung } else if (mWaveFormat == WAVE_FORMAT_IEEE_FLOAT) { 26375e6e22434d6fb3021738dcef644109374e75643Andy Hung if (mBitsPerSample != 32) { // TODO we don't support double 26475e6e22434d6fb3021738dcef644109374e75643Andy Hung return ERROR_UNSUPPORTED; 26575e6e22434d6fb3021738dcef644109374e75643Andy Hung } 26675e6e22434d6fb3021738dcef644109374e75643Andy Hung } 26775e6e22434d6fb3021738dcef644109374e75643Andy Hung else if (mWaveFormat == WAVE_FORMAT_MSGSM) { 26875e6e22434d6fb3021738dcef644109374e75643Andy Hung if (mBitsPerSample != 0) { 26975e6e22434d6fb3021738dcef644109374e75643Andy Hung return ERROR_UNSUPPORTED; 27075e6e22434d6fb3021738dcef644109374e75643Andy Hung } 27175e6e22434d6fb3021738dcef644109374e75643Andy Hung } else if (mWaveFormat == WAVE_FORMAT_MULAW || mWaveFormat == WAVE_FORMAT_ALAW) { 27275e6e22434d6fb3021738dcef644109374e75643Andy Hung if (mBitsPerSample != 8) { 27375e6e22434d6fb3021738dcef644109374e75643Andy Hung return ERROR_UNSUPPORTED; 27475e6e22434d6fb3021738dcef644109374e75643Andy Hung } 27575e6e22434d6fb3021738dcef644109374e75643Andy Hung } else { 27675e6e22434d6fb3021738dcef644109374e75643Andy Hung return ERROR_UNSUPPORTED; 27775e6e22434d6fb3021738dcef644109374e75643Andy Hung } 27875e6e22434d6fb3021738dcef644109374e75643Andy Hung 2790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mValidFormat = true; 2800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } else if (!memcmp(chunkHeader, "data", 4)) { 2810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mValidFormat) { 2820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mDataOffset = offset; 2830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mDataSize = chunkSize; 2840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 285f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mTrackMeta = new MetaData; 28642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber 28742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber switch (mWaveFormat) { 28842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber case WAVE_FORMAT_PCM: 28975e6e22434d6fb3021738dcef644109374e75643Andy Hung case WAVE_FORMAT_IEEE_FLOAT: 29042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber mTrackMeta->setCString( 29142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 29242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber break; 29342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber case WAVE_FORMAT_ALAW: 29442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber mTrackMeta->setCString( 29542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_ALAW); 29642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber break; 297ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen case WAVE_FORMAT_MSGSM: 298ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen mTrackMeta->setCString( 299ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MSGSM); 300ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen break; 30142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber default: 302f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK_EQ(mWaveFormat, (uint16_t)WAVE_FORMAT_MULAW); 30342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber mTrackMeta->setCString( 30442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_MLAW); 30542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber break; 30642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber } 30742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber 308f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mTrackMeta->setInt32(kKeyChannelCount, mNumChannels); 3093bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi mTrackMeta->setInt32(kKeyChannelMask, mChannelMask); 310f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mTrackMeta->setInt32(kKeySampleRate, mSampleRate); 311f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 312ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen int64_t durationUs = 0; 313ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen if (mWaveFormat == WAVE_FORMAT_MSGSM) { 314ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen // 65 bytes decode to 320 8kHz samples 315ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen durationUs = 316ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen 1000000LL * (mDataSize / 65 * 320) / 8000; 317ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen } else { 318ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen size_t bytesPerSample = mBitsPerSample >> 3; 319e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake 320e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake if (!bytesPerSample || !mNumChannels) 321e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake return ERROR_MALFORMED; 322e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake 323e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake size_t num_samples = mDataSize / (mNumChannels * bytesPerSample); 324e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake 325e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake if (!mSampleRate) 326e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake return ERROR_MALFORMED; 327e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake 328ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen durationUs = 329e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake 1000000LL * num_samples / mSampleRate; 330ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen } 331f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 332f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mTrackMeta->setInt64(kKeyDuration, durationUs); 333f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 3340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 3350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber offset += chunkSize; 3390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 3420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberconst size_t WAVSource::kMaxFrameSize = 32768; 3450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::WAVSource( 3470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber const sp<DataSource> &dataSource, 348f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber const sp<MetaData> &meta, 34942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber uint16_t waveFormat, 350f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber int32_t bitsPerSample, 351c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset, size_t size) 3520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber : mDataSource(dataSource), 353f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mMeta(meta), 35442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber mWaveFormat(waveFormat), 355f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mSampleRate(0), 356f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mNumChannels(0), 357f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mBitsPerSample(bitsPerSample), 3580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mOffset(offset), 3590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mSize(size), 3600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted(false), 3610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup(NULL) { 362f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber CHECK(mMeta->findInt32(kKeySampleRate, &mSampleRate)); 363f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber CHECK(mMeta->findInt32(kKeyChannelCount, &mNumChannels)); 364bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 365bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mMeta->setInt32(kKeyMaxInputSize, kMaxFrameSize); 3660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::~WAVSource() { 3690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mStarted) { 3700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber stop(); 3710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 37484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t WAVSource::start(MetaData * /* params */) { 3753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("WAVSource::start"); 3760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber CHECK(!mStarted); 3780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup = new MediaBufferGroup; 3800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup->add_buffer(new MediaBuffer(kMaxFrameSize)); 3810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 382f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber if (mBitsPerSample == 8) { 383f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber // As a temporary buffer for 8->16 bit conversion. 384f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mGroup->add_buffer(new MediaBuffer(kMaxFrameSize)); 385f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber } 386f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 3870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos = mOffset; 3880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted = true; 3900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 3920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::stop() { 3953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("WAVSource::stop"); 3960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber CHECK(mStarted); 3980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber delete mGroup; 4000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup = NULL; 4010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted = false; 4030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 4050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 4060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVSource::getFormat() { 4083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("WAVSource::getFormat"); 4090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 410f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber return mMeta; 4110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 4120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::read( 4140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBuffer **out, const ReadOptions *options) { 4150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *out = NULL; 4160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int64_t seekTimeUs; 418abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 419abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) { 420ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen int64_t pos = 0; 421ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen 422ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen if (mWaveFormat == WAVE_FORMAT_MSGSM) { 423ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen // 65 bytes decode to 320 8kHz samples 424ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen int64_t samplenumber = (seekTimeUs * mSampleRate) / 1000000; 425ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen int64_t framenumber = samplenumber / 320; 426ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen pos = framenumber * 65; 427ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen } else { 428ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen pos = (seekTimeUs * mSampleRate) / 1000000 * mNumChannels * (mBitsPerSample >> 3); 429ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen } 430a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn if (pos > (off64_t)mSize) { 4310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber pos = mSize; 4320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 4330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos = pos + mOffset; 4340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 4350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBuffer *buffer; 4370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber status_t err = mGroup->acquire_buffer(&buffer); 4380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (err != OK) { 4390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return err; 4400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 4410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4429b1797fed7065be05f8fb7a36d1a27e0df3cb7abcong.zhou // make sure that maxBytesToRead is multiple of 3, in 24-bit case 443104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber size_t maxBytesToRead = 4449b1797fed7065be05f8fb7a36d1a27e0df3cb7abcong.zhou mBitsPerSample == 8 ? kMaxFrameSize / 2 : 4459b1797fed7065be05f8fb7a36d1a27e0df3cb7abcong.zhou (mBitsPerSample == 24 ? 3*(kMaxFrameSize/3): kMaxFrameSize); 446104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber 447104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber size_t maxBytesAvailable = 448c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong (mCurrentPos - mOffset >= (off64_t)mSize) 449104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber ? 0 : mSize - (mCurrentPos - mOffset); 450104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber 451104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber if (maxBytesToRead > maxBytesAvailable) { 452104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber maxBytesToRead = maxBytesAvailable; 453104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber } 454104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber 455ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen if (mWaveFormat == WAVE_FORMAT_MSGSM) { 456ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen // Microsoft packs 2 frames into 65 bytes, rather than using separate 33-byte frames, 457ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen // so read multiples of 65, and use smaller buffers to account for ~10:1 expansion ratio 458ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen if (maxBytesToRead > 1024) { 459ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen maxBytesToRead = 1024; 460ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen } 461ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen maxBytesToRead = (maxBytesToRead / 65) * 65; 46241d3f579d2c166984958263533284209b90c87d5Marco Nelissen } else { 46341d3f579d2c166984958263533284209b90c87d5Marco Nelissen // read only integral amounts of audio unit frames. 46441d3f579d2c166984958263533284209b90c87d5Marco Nelissen const size_t inputUnitFrameSize = mNumChannels * mBitsPerSample / 8; 46541d3f579d2c166984958263533284209b90c87d5Marco Nelissen maxBytesToRead -= maxBytesToRead % inputUnitFrameSize; 466ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen } 467ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen 4680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber ssize_t n = mDataSource->readAt( 469f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mCurrentPos, buffer->data(), 470104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber maxBytesToRead); 4710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (n <= 0) { 4730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->release(); 4740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer = NULL; 4750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_END_OF_STREAM; 4770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 4780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->set_range(0, n); 480f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 48175e6e22434d6fb3021738dcef644109374e75643Andy Hung // TODO: add capability to return data as float PCM instead of 16 bit PCM. 48275e6e22434d6fb3021738dcef644109374e75643Andy Hung if (mWaveFormat == WAVE_FORMAT_PCM) { 48342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber if (mBitsPerSample == 8) { 48442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber // Convert 8-bit unsigned samples to 16-bit signed. 485f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 48675e6e22434d6fb3021738dcef644109374e75643Andy Hung // Create new buffer with 2 byte wide samples 48742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber MediaBuffer *tmp; 488f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK_EQ(mGroup->acquire_buffer(&tmp), (status_t)OK); 48942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber tmp->set_range(0, 2 * n); 490f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 49175e6e22434d6fb3021738dcef644109374e75643Andy Hung memcpy_to_i16_from_u8((int16_t *)tmp->data(), (const uint8_t *)buffer->data(), n); 49242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber buffer->release(); 49342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber buffer = tmp; 49442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber } else if (mBitsPerSample == 24) { 49575e6e22434d6fb3021738dcef644109374e75643Andy Hung // Convert 24-bit signed samples to 16-bit signed in place 49675e6e22434d6fb3021738dcef644109374e75643Andy Hung const size_t numSamples = n / 3; 49742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber 49875e6e22434d6fb3021738dcef644109374e75643Andy Hung memcpy_to_i16_from_p24((int16_t *)buffer->data(), (const uint8_t *)buffer->data(), numSamples); 49975e6e22434d6fb3021738dcef644109374e75643Andy Hung buffer->set_range(0, 2 * numSamples); 50075e6e22434d6fb3021738dcef644109374e75643Andy Hung } else if (mBitsPerSample == 32) { 50175e6e22434d6fb3021738dcef644109374e75643Andy Hung // Convert 32-bit signed samples to 16-bit signed in place 50275e6e22434d6fb3021738dcef644109374e75643Andy Hung const size_t numSamples = n / 4; 503984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber 50475e6e22434d6fb3021738dcef644109374e75643Andy Hung memcpy_to_i16_from_i32((int16_t *)buffer->data(), (const int32_t *)buffer->data(), numSamples); 50575e6e22434d6fb3021738dcef644109374e75643Andy Hung buffer->set_range(0, 2 * numSamples); 50675e6e22434d6fb3021738dcef644109374e75643Andy Hung } 50775e6e22434d6fb3021738dcef644109374e75643Andy Hung } else if (mWaveFormat == WAVE_FORMAT_IEEE_FLOAT) { 50875e6e22434d6fb3021738dcef644109374e75643Andy Hung if (mBitsPerSample == 32) { 50975e6e22434d6fb3021738dcef644109374e75643Andy Hung // Convert 32-bit float samples to 16-bit signed in place 51075e6e22434d6fb3021738dcef644109374e75643Andy Hung const size_t numSamples = n / 4; 51142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber 51275e6e22434d6fb3021738dcef644109374e75643Andy Hung memcpy_to_i16_from_float((int16_t *)buffer->data(), (const float *)buffer->data(), numSamples); 51375e6e22434d6fb3021738dcef644109374e75643Andy Hung buffer->set_range(0, 2 * numSamples); 51442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber } 515f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber } 516f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 517ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen int64_t timeStampUs = 0; 518ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen 519ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen if (mWaveFormat == WAVE_FORMAT_MSGSM) { 520ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen timeStampUs = 1000000LL * (mCurrentPos - mOffset) * 320 / 65 / mSampleRate; 521ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen } else { 522ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen size_t bytesPerSample = mBitsPerSample >> 3; 523ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen timeStampUs = 1000000LL * (mCurrentPos - mOffset) 524ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen / (mNumChannels * bytesPerSample) / mSampleRate; 525ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen } 526f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 527ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen buffer->meta_data()->setInt64(kKeyTime, timeStampUs); 5280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 5298bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 530f1e10e8ed74cac805d601139882378a1f450fe94James Dong mCurrentPos += n; 5310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 5320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *out = buffer; 5330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 5340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 5350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 5360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 5370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber//////////////////////////////////////////////////////////////////////////////// 5380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 5390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberbool SniffWAV( 5405a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence, 5415a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber sp<AMessage> *) { 5420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber char header[12]; 5430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) { 5440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return false; 5450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 5460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 5470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) { 5480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return false; 5490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 5500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 55170d3e260edcd42972864bf501337f0b1a187657dJames Dong sp<MediaExtractor> extractor = new WAVExtractor(source); 55270d3e260edcd42972864bf501337f0b1a187657dJames Dong if (extractor->countTracks() == 0) { 55370d3e260edcd42972864bf501337f0b1a187657dJames Dong return false; 55470d3e260edcd42972864bf501337f0b1a187657dJames Dong } 55570d3e260edcd42972864bf501337f0b1a187657dJames Dong 5560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_WAV; 5570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *confidence = 0.3f; 5580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 5590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return true; 5600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 5610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 5620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} // namespace android 563