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