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 2175226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen#include "WAVExtractor.h" 220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2375e6e22434d6fb3021738dcef644109374e75643Andy Hung#include <audio_utils/primitives.h> 242a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen#include <media/DataSourceBase.h> 253d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen#include <media/MediaTrack.h> 26f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaDefs.h> 290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaErrors.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"; 48bd152eb21ba91e62c53910c6d511aea2af89b656Viraj Karandikarstatic const char* AMBISONIC_SUBFORMAT = "\x00\x00\x21\x07\xD3\x11\x86\x44\xC8\xC1\xCA\x00\x00\x00"; 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 583d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenstruct WAVSource : public MediaTrack { 590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber WAVSource( 602a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen DataSourceBase *dataSource, 613d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen MetaDataBase &meta, 6242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber uint16_t waveFormat, 63f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber int32_t bitsPerSample, 64c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset, size_t size); 650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 663d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen virtual status_t start(MetaDataBase *params = NULL); 670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual status_t stop(); 683d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen virtual status_t getFormat(MetaDataBase &meta); 690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual status_t read( 711889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang MediaBufferBase **buffer, const ReadOptions *options = NULL); 720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 73cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung virtual bool supportNonblockingRead() { return true; } 74cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung 750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprotected: 760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber virtual ~WAVSource(); 770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprivate: 790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber static const size_t kMaxFrameSize; 800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 812a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen DataSourceBase *mDataSource; 823d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen MetaDataBase &mMeta; 8342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber uint16_t mWaveFormat; 840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int32_t mSampleRate; 850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int32_t mNumChannels; 86f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber int32_t mBitsPerSample; 87c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t mOffset; 880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t mSize; 890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber bool mStarted; 900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber MediaBufferGroup *mGroup; 91c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t mCurrentPos; 920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber WAVSource(const WAVSource &); 940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber WAVSource &operator=(const WAVSource &); 950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}; 960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 972a243f08193fe9ff1afe018e9953f01c44ced9deMarco NelissenWAVExtractor::WAVExtractor(DataSourceBase *source) 980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber : mDataSource(source), 993bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi mValidFormat(false), 1003bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi mChannelMask(CHANNEL_MASK_USE_CHANNEL_ORDER) { 1010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mInitCheck = init(); 1020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::~WAVExtractor() { 1050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1073d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenstatus_t WAVExtractor::getMetaData(MetaDataBase &meta) { 1083d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.clear(); 1093d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen if (mInitCheck == OK) { 1103d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_WAV); 1117be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 1127be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 1133d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen return OK; 1147be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 1157be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 1160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersize_t WAVExtractor::countTracks() { 1170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return mInitCheck == OK ? 1 : 0; 1180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1203d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco NelissenMediaTrack *WAVExtractor::getTrack(size_t index) { 1210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mInitCheck != OK || index > 0) { 1220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NULL; 1230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return new WAVSource( 126f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mDataSource, mTrackMeta, 12742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber mWaveFormat, mBitsPerSample, mDataOffset, mDataSize); 1280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1303d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenstatus_t WAVExtractor::getTrackMetaData( 1313d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen MetaDataBase &meta, 13284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber size_t index, uint32_t /* flags */) { 1330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mInitCheck != OK || index > 0) { 1343d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen return UNKNOWN_ERROR; 1350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1373d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta = mTrackMeta; 1383d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen return OK; 1390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 1400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVExtractor::init() { 1420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint8_t header[12]; 1430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mDataSource->readAt( 1440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 0, header, sizeof(header)) < (ssize_t)sizeof(header)) { 1450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) { 1490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t totalSize = U32_LE_AT(&header[4]); 1530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 154c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset = 12; 1550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber size_t remainingSize = totalSize; 1560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber while (remainingSize >= 8) { 1570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint8_t chunkHeader[8]; 1580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mDataSource->readAt(offset, chunkHeader, 8) < 8) { 1590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber remainingSize -= 8; 1630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber offset += 8; 164f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 1650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber uint32_t chunkSize = U32_LE_AT(&chunkHeader[4]); 1660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (chunkSize > remainingSize) { 1680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (!memcmp(chunkHeader, "fmt ", 4)) { 1720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (chunkSize < 16) { 1730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1763bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi uint8_t formatSpec[40]; 1773bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mDataSource->readAt(offset, formatSpec, 2) < 2) { 1780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 1790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 18142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber mWaveFormat = U16_LE_AT(formatSpec); 18242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber if (mWaveFormat != WAVE_FORMAT_PCM 18375e6e22434d6fb3021738dcef644109374e75643Andy Hung && mWaveFormat != WAVE_FORMAT_IEEE_FLOAT 18442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber && mWaveFormat != WAVE_FORMAT_ALAW 1853bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi && mWaveFormat != WAVE_FORMAT_MULAW 186ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen && mWaveFormat != WAVE_FORMAT_MSGSM 1873bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi && mWaveFormat != WAVE_FORMAT_EXTENSIBLE) { 1880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_UNSUPPORTED; 1890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 1900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 1913bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi uint8_t fmtSize = 16; 1923bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mWaveFormat == WAVE_FORMAT_EXTENSIBLE) { 1933bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi fmtSize = 40; 1943bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 1953bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mDataSource->readAt(offset, formatSpec, fmtSize) < fmtSize) { 1963bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi return NO_INIT; 1973bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 1983bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 1990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mNumChannels = U16_LE_AT(&formatSpec[2]); 200778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz 201778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz if (mNumChannels < 1 || mNumChannels > 8) { 202778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz ALOGE("Unsupported number of channels (%d)", mNumChannels); 203778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz return ERROR_UNSUPPORTED; 204778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz } 205778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz 2063bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mWaveFormat != WAVE_FORMAT_EXTENSIBLE) { 207778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz if (mNumChannels != 1 && mNumChannels != 2) { 2083bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi ALOGW("More than 2 channels (%d) in non-WAVE_EXT, unknown channel mask", 2093bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi mNumChannels); 2103bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 2120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mSampleRate = U32_LE_AT(&formatSpec[4]); 2140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 215f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber if (mSampleRate == 0) { 216f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber return ERROR_MALFORMED; 217f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber } 218f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 219f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mBitsPerSample = U16_LE_AT(&formatSpec[14]); 220f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 2213bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (mWaveFormat == WAVE_FORMAT_EXTENSIBLE) { 2223bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi uint16_t validBitsPerSample = U16_LE_AT(&formatSpec[18]); 2233bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if (validBitsPerSample != mBitsPerSample) { 22406f6ae34c735640dccdaca6ab1567d8afc9d3938Jean-Michel Trivi if (validBitsPerSample != 0) { 22572b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi ALOGE("validBits(%d) != bitsPerSample(%d) are not supported", 22672b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi validBitsPerSample, mBitsPerSample); 22772b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi return ERROR_UNSUPPORTED; 22872b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi } else { 22972b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi // we only support valitBitsPerSample == bitsPerSample but some WAV_EXT 23072b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi // writers don't correctly set the valid bits value, and leave it at 0. 23172b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi ALOGW("WAVE_EXT has 0 valid bits per sample, ignoring"); 23272b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi } 2333bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2343bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 2353bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi mChannelMask = U32_LE_AT(&formatSpec[20]); 2363bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi ALOGV("numChannels=%d channelMask=0x%x", mNumChannels, mChannelMask); 2373bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if ((mChannelMask >> 18) != 0) { 2383bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi ALOGE("invalid channel mask 0x%x", mChannelMask); 2393bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi return ERROR_MALFORMED; 2403bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2413bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 2423bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi if ((mChannelMask != CHANNEL_MASK_USE_CHANNEL_ORDER) 2433bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi && (popcount(mChannelMask) != mNumChannels)) { 2443bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi ALOGE("invalid number of channels (%d) in channel mask (0x%x)", 2453bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi popcount(mChannelMask), mChannelMask); 2463bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi return ERROR_MALFORMED; 2473bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2483bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 2493bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi // In a WAVE_EXT header, the first two bytes of the GUID stored at byte 24 contain 2503bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi // the sample format, using the same definitions as a regular WAV header 2513bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi mWaveFormat = U16_LE_AT(&formatSpec[24]); 252bd152eb21ba91e62c53910c6d511aea2af89b656Viraj Karandikar if (memcmp(&formatSpec[26], WAVEEXT_SUBFORMAT, 14) && 253bd152eb21ba91e62c53910c6d511aea2af89b656Viraj Karandikar memcmp(&formatSpec[26], AMBISONIC_SUBFORMAT, 14)) { 2543bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi ALOGE("unsupported GUID"); 2553bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi return ERROR_UNSUPPORTED; 2563bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2573bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi } 2583bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi 25975e6e22434d6fb3021738dcef644109374e75643Andy Hung if (mWaveFormat == WAVE_FORMAT_PCM) { 26075e6e22434d6fb3021738dcef644109374e75643Andy Hung if (mBitsPerSample != 8 && mBitsPerSample != 16 26175e6e22434d6fb3021738dcef644109374e75643Andy Hung && mBitsPerSample != 24 && mBitsPerSample != 32) { 26275e6e22434d6fb3021738dcef644109374e75643Andy Hung return ERROR_UNSUPPORTED; 26375e6e22434d6fb3021738dcef644109374e75643Andy Hung } 26475e6e22434d6fb3021738dcef644109374e75643Andy Hung } else if (mWaveFormat == WAVE_FORMAT_IEEE_FLOAT) { 26575e6e22434d6fb3021738dcef644109374e75643Andy Hung if (mBitsPerSample != 32) { // TODO we don't support double 26675e6e22434d6fb3021738dcef644109374e75643Andy Hung return ERROR_UNSUPPORTED; 26775e6e22434d6fb3021738dcef644109374e75643Andy Hung } 26875e6e22434d6fb3021738dcef644109374e75643Andy Hung } 26975e6e22434d6fb3021738dcef644109374e75643Andy Hung else if (mWaveFormat == WAVE_FORMAT_MSGSM) { 27075e6e22434d6fb3021738dcef644109374e75643Andy Hung if (mBitsPerSample != 0) { 27175e6e22434d6fb3021738dcef644109374e75643Andy Hung return ERROR_UNSUPPORTED; 27275e6e22434d6fb3021738dcef644109374e75643Andy Hung } 27375e6e22434d6fb3021738dcef644109374e75643Andy Hung } else if (mWaveFormat == WAVE_FORMAT_MULAW || mWaveFormat == WAVE_FORMAT_ALAW) { 27475e6e22434d6fb3021738dcef644109374e75643Andy Hung if (mBitsPerSample != 8) { 27575e6e22434d6fb3021738dcef644109374e75643Andy Hung return ERROR_UNSUPPORTED; 27675e6e22434d6fb3021738dcef644109374e75643Andy Hung } 27775e6e22434d6fb3021738dcef644109374e75643Andy Hung } else { 27875e6e22434d6fb3021738dcef644109374e75643Andy Hung return ERROR_UNSUPPORTED; 27975e6e22434d6fb3021738dcef644109374e75643Andy Hung } 28075e6e22434d6fb3021738dcef644109374e75643Andy Hung 2810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mValidFormat = true; 2820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } else if (!memcmp(chunkHeader, "data", 4)) { 2830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mValidFormat) { 2840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mDataOffset = offset; 2850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mDataSize = chunkSize; 2860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 2873d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen mTrackMeta.clear(); 28842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber 28942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber switch (mWaveFormat) { 29042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber case WAVE_FORMAT_PCM: 29175e6e22434d6fb3021738dcef644109374e75643Andy Hung case WAVE_FORMAT_IEEE_FLOAT: 2923d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen mTrackMeta.setCString( 29342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 29442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber break; 29542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber case WAVE_FORMAT_ALAW: 2963d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen mTrackMeta.setCString( 29742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_ALAW); 29842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber break; 299ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen case WAVE_FORMAT_MSGSM: 3003d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen mTrackMeta.setCString( 301ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MSGSM); 302ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen break; 30342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber default: 304f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK_EQ(mWaveFormat, (uint16_t)WAVE_FORMAT_MULAW); 3053d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen mTrackMeta.setCString( 30642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_MLAW); 30742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber break; 30842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber } 30942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber 3103d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen mTrackMeta.setInt32(kKeyChannelCount, mNumChannels); 3113d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen mTrackMeta.setInt32(kKeyChannelMask, mChannelMask); 3123d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen mTrackMeta.setInt32(kKeySampleRate, mSampleRate); 3133d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen mTrackMeta.setInt32(kKeyPcmEncoding, kAudioEncodingPcm16bit); 314f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 315ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen int64_t durationUs = 0; 316ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen if (mWaveFormat == WAVE_FORMAT_MSGSM) { 317ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen // 65 bytes decode to 320 8kHz samples 318ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen durationUs = 319ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen 1000000LL * (mDataSize / 65 * 320) / 8000; 320ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen } else { 321ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen size_t bytesPerSample = mBitsPerSample >> 3; 322e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake 323e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake if (!bytesPerSample || !mNumChannels) 324e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake return ERROR_MALFORMED; 325e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake 326e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake size_t num_samples = mDataSize / (mNumChannels * bytesPerSample); 327e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake 328e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake if (!mSampleRate) 329e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake return ERROR_MALFORMED; 330e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake 331ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen durationUs = 332e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake 1000000LL * num_samples / mSampleRate; 333ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen } 334f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 3353d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen mTrackMeta.setInt64(kKeyDuration, durationUs); 336f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 3370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 3380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber offset += chunkSize; 3420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return NO_INIT; 3450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberconst size_t WAVSource::kMaxFrameSize = 32768; 3480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::WAVSource( 3502a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen DataSourceBase *dataSource, 3513d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen MetaDataBase &meta, 35242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber uint16_t waveFormat, 353f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber int32_t bitsPerSample, 354c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t offset, size_t size) 3550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber : mDataSource(dataSource), 356f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mMeta(meta), 35742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber mWaveFormat(waveFormat), 358f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mSampleRate(0), 359f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mNumChannels(0), 360f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mBitsPerSample(bitsPerSample), 3610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mOffset(offset), 3620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mSize(size), 3630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted(false), 3640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup(NULL) { 3653d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen CHECK(mMeta.findInt32(kKeySampleRate, &mSampleRate)); 3663d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen CHECK(mMeta.findInt32(kKeyChannelCount, &mNumChannels)); 367bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 3683d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen mMeta.setInt32(kKeyMaxInputSize, kMaxFrameSize); 3690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::~WAVSource() { 3720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (mStarted) { 3730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber stop(); 3740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 3750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3773d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenstatus_t WAVSource::start(MetaDataBase * /* params */) { 3783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("WAVSource::start"); 3790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber CHECK(!mStarted); 3810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 382cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung // some WAV files may have large audio buffers that use shared memory transfer. 383cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung mGroup = new MediaBufferGroup(4 /* buffers */, kMaxFrameSize); 3840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 385f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber if (mBitsPerSample == 8) { 386f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber // As a temporary buffer for 8->16 bit conversion. 3871889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang mGroup->add_buffer(MediaBufferBase::Create(kMaxFrameSize)); 388f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber } 389f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 3900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos = mOffset; 3910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted = true; 3930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 3950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 3960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 3970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::stop() { 3983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("WAVSource::stop"); 3990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber CHECK(mStarted); 4010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber delete mGroup; 4030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mGroup = NULL; 4040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mStarted = false; 4060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 4080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 4090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4103d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissenstatus_t WAVSource::getFormat(MetaDataBase &meta) { 4113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("WAVSource::getFormat"); 4120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4133d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen meta = mMeta; 4143d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen return OK; 4150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 4160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::read( 4181889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang MediaBufferBase **out, const ReadOptions *options) { 4190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *out = NULL; 4200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 421cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung if (options != nullptr && options->getNonBlocking() && !mGroup->has_buffers()) { 422cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung return WOULD_BLOCK; 423cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung } 424cdeb6603d862cec4adac7c39f3b8b240f2b645dcAndy Hung 4250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber int64_t seekTimeUs; 426abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 427abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) { 428ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen int64_t pos = 0; 429ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen 430ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen if (mWaveFormat == WAVE_FORMAT_MSGSM) { 431ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen // 65 bytes decode to 320 8kHz samples 432ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen int64_t samplenumber = (seekTimeUs * mSampleRate) / 1000000; 433ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen int64_t framenumber = samplenumber / 320; 434ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen pos = framenumber * 65; 435ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen } else { 436ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen pos = (seekTimeUs * mSampleRate) / 1000000 * mNumChannels * (mBitsPerSample >> 3); 437ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen } 438a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn if (pos > (off64_t)mSize) { 4390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber pos = mSize; 4400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 4410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber mCurrentPos = pos + mOffset; 4420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 4430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4441889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang MediaBufferBase *buffer; 4450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber status_t err = mGroup->acquire_buffer(&buffer); 4460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (err != OK) { 4470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return err; 4480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 4490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4509b1797fed7065be05f8fb7a36d1a27e0df3cb7abcong.zhou // make sure that maxBytesToRead is multiple of 3, in 24-bit case 451104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber size_t maxBytesToRead = 4529b1797fed7065be05f8fb7a36d1a27e0df3cb7abcong.zhou mBitsPerSample == 8 ? kMaxFrameSize / 2 : 4539b1797fed7065be05f8fb7a36d1a27e0df3cb7abcong.zhou (mBitsPerSample == 24 ? 3*(kMaxFrameSize/3): kMaxFrameSize); 454104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber 455104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber size_t maxBytesAvailable = 456c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong (mCurrentPos - mOffset >= (off64_t)mSize) 457104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber ? 0 : mSize - (mCurrentPos - mOffset); 458104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber 459104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber if (maxBytesToRead > maxBytesAvailable) { 460104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber maxBytesToRead = maxBytesAvailable; 461104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber } 462104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber 463ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen if (mWaveFormat == WAVE_FORMAT_MSGSM) { 464ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen // Microsoft packs 2 frames into 65 bytes, rather than using separate 33-byte frames, 465ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen // so read multiples of 65, and use smaller buffers to account for ~10:1 expansion ratio 466ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen if (maxBytesToRead > 1024) { 467ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen maxBytesToRead = 1024; 468ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen } 469ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen maxBytesToRead = (maxBytesToRead / 65) * 65; 47041d3f579d2c166984958263533284209b90c87d5Marco Nelissen } else { 47141d3f579d2c166984958263533284209b90c87d5Marco Nelissen // read only integral amounts of audio unit frames. 47241d3f579d2c166984958263533284209b90c87d5Marco Nelissen const size_t inputUnitFrameSize = mNumChannels * mBitsPerSample / 8; 47341d3f579d2c166984958263533284209b90c87d5Marco Nelissen maxBytesToRead -= maxBytesToRead % inputUnitFrameSize; 474ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen } 475ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen 4760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber ssize_t n = mDataSource->readAt( 477f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber mCurrentPos, buffer->data(), 478104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber maxBytesToRead); 4790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (n <= 0) { 4810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->release(); 4820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer = NULL; 4830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return ERROR_END_OF_STREAM; 4850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 4860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 4870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber buffer->set_range(0, n); 488f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 48975e6e22434d6fb3021738dcef644109374e75643Andy Hung // TODO: add capability to return data as float PCM instead of 16 bit PCM. 49075e6e22434d6fb3021738dcef644109374e75643Andy Hung if (mWaveFormat == WAVE_FORMAT_PCM) { 49142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber if (mBitsPerSample == 8) { 49242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber // Convert 8-bit unsigned samples to 16-bit signed. 493f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 49475e6e22434d6fb3021738dcef644109374e75643Andy Hung // Create new buffer with 2 byte wide samples 4951889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang MediaBufferBase *tmp; 496f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK_EQ(mGroup->acquire_buffer(&tmp), (status_t)OK); 49742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber tmp->set_range(0, 2 * n); 498f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 49975e6e22434d6fb3021738dcef644109374e75643Andy Hung memcpy_to_i16_from_u8((int16_t *)tmp->data(), (const uint8_t *)buffer->data(), n); 50042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber buffer->release(); 50142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber buffer = tmp; 50242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber } else if (mBitsPerSample == 24) { 50375e6e22434d6fb3021738dcef644109374e75643Andy Hung // Convert 24-bit signed samples to 16-bit signed in place 50475e6e22434d6fb3021738dcef644109374e75643Andy Hung const size_t numSamples = n / 3; 50542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber 50675e6e22434d6fb3021738dcef644109374e75643Andy Hung memcpy_to_i16_from_p24((int16_t *)buffer->data(), (const uint8_t *)buffer->data(), numSamples); 50775e6e22434d6fb3021738dcef644109374e75643Andy Hung buffer->set_range(0, 2 * numSamples); 50875e6e22434d6fb3021738dcef644109374e75643Andy Hung } else if (mBitsPerSample == 32) { 50975e6e22434d6fb3021738dcef644109374e75643Andy Hung // Convert 32-bit signed samples to 16-bit signed in place 51075e6e22434d6fb3021738dcef644109374e75643Andy Hung const size_t numSamples = n / 4; 511984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber 51275e6e22434d6fb3021738dcef644109374e75643Andy Hung memcpy_to_i16_from_i32((int16_t *)buffer->data(), (const int32_t *)buffer->data(), numSamples); 51375e6e22434d6fb3021738dcef644109374e75643Andy Hung buffer->set_range(0, 2 * numSamples); 51475e6e22434d6fb3021738dcef644109374e75643Andy Hung } 51575e6e22434d6fb3021738dcef644109374e75643Andy Hung } else if (mWaveFormat == WAVE_FORMAT_IEEE_FLOAT) { 51675e6e22434d6fb3021738dcef644109374e75643Andy Hung if (mBitsPerSample == 32) { 51775e6e22434d6fb3021738dcef644109374e75643Andy Hung // Convert 32-bit float samples to 16-bit signed in place 51875e6e22434d6fb3021738dcef644109374e75643Andy Hung const size_t numSamples = n / 4; 51942d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber 52075e6e22434d6fb3021738dcef644109374e75643Andy Hung memcpy_to_i16_from_float((int16_t *)buffer->data(), (const float *)buffer->data(), numSamples); 52175e6e22434d6fb3021738dcef644109374e75643Andy Hung buffer->set_range(0, 2 * numSamples); 52242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber } 523f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber } 524f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 525ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen int64_t timeStampUs = 0; 526ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen 527ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen if (mWaveFormat == WAVE_FORMAT_MSGSM) { 528ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen timeStampUs = 1000000LL * (mCurrentPos - mOffset) * 320 / 65 / mSampleRate; 529ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen } else { 530ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen size_t bytesPerSample = mBitsPerSample >> 3; 531ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen timeStampUs = 1000000LL * (mCurrentPos - mOffset) 532ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen / (mNumChannels * bytesPerSample) / mSampleRate; 533ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen } 534f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber 5353d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen buffer->meta_data().setInt64(kKeyTime, timeStampUs); 5360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 5373d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen buffer->meta_data().setInt32(kKeyIsSyncFrame, 1); 538f1e10e8ed74cac805d601139882378a1f450fe94James Dong mCurrentPos += n; 5390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 5400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *out = buffer; 5410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 5420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber return OK; 5430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 5440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 5450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber//////////////////////////////////////////////////////////////////////////////// 5460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 54775226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissenstatic MediaExtractor* CreateExtractor( 5482a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen DataSourceBase *source, 54917e172b4c3c87ecaa7c87eecc42b4dc47e3e9734Dongwon Kang void *) { 55075226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen return new WAVExtractor(source); 55175226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen} 55275226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen 55375226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissenstatic MediaExtractor::CreatorFunc Sniff( 5542a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen DataSourceBase *source, 55575226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen float *confidence, 55617e172b4c3c87ecaa7c87eecc42b4dc47e3e9734Dongwon Kang void **, 55717e172b4c3c87ecaa7c87eecc42b4dc47e3e9734Dongwon Kang MediaExtractor::FreeMetaFunc *) { 5580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber char header[12]; 5590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) { 56075226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen return NULL; 5610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 5620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 5630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) { 56475226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen return NULL; 5650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber } 5660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 5677d880c31d2079299000b036c6ae742dc695a5b19Marco Nelissen MediaExtractor *extractor = new WAVExtractor(source); 5687d880c31d2079299000b036c6ae742dc695a5b19Marco Nelissen int numTracks = extractor->countTracks(); 5697d880c31d2079299000b036c6ae742dc695a5b19Marco Nelissen delete extractor; 5707d880c31d2079299000b036c6ae742dc695a5b19Marco Nelissen if (numTracks == 0) { 57175226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen return NULL; 57270d3e260edcd42972864bf501337f0b1a187657dJames Dong } 57370d3e260edcd42972864bf501337f0b1a187657dJames Dong 5740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *confidence = 0.3f; 5750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 57675226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen return CreateExtractor; 57775226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen} 57875226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen 57975226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissenextern "C" { 58075226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen// This is the only symbol that needs to be exported 58175226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen__attribute__ ((visibility ("default"))) 58275226177f20a176d50e3e53bbb34067cb49112c3Marco NelissenMediaExtractor::ExtractorDef GETEXTRACTORDEF() { 58375226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen return { 58475226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen MediaExtractor::EXTRACTORDEF_VERSION, 58575226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen UUID("7d613858-5837-4a38-84c5-332d1cddee27"), 58675226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen 1, // version 58775226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen "WAV Extractor", 58875226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen Sniff 58975226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen }; 5900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber} 5910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber 59275226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen} // extern "C" 59375226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen 59475226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen} // namespace android 595