10dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber/*
20dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * Copyright (C) 2009 The Android Open Source Project
30dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *
40dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
50dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * you may not use this file except in compliance with the License.
60dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * You may obtain a copy of the License at
70dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *
80dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
90dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber *
100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * Unless required by applicable law or agreed to in writing, software
110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * See the License for the specific language governing permissions and
140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber * limitations under the License.
150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber */
160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber//#define LOG_NDEBUG 0
180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#define LOG_TAG "WAVExtractor"
190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <utils/Log.h>
200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include "include/WAVExtractor.h"
220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2375e6e22434d6fb3021738dcef644109374e75643Andy Hung#include <audio_utils/primitives.h>
24f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/DataSource.h>
260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaBufferGroup.h>
270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaDefs.h>
280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaErrors.h>
290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaSource.h>
300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MetaData.h>
310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <utils/String8.h>
323bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi#include <cutils/bitops.h>
333bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
343bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi#define CHANNEL_MASK_USE_CHANNEL_ORDER 0
350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubernamespace android {
370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huberenum {
393bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi    WAVE_FORMAT_PCM        = 0x0001,
4075e6e22434d6fb3021738dcef644109374e75643Andy Hung    WAVE_FORMAT_IEEE_FLOAT = 0x0003,
413bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi    WAVE_FORMAT_ALAW       = 0x0006,
423bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi    WAVE_FORMAT_MULAW      = 0x0007,
43ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen    WAVE_FORMAT_MSGSM      = 0x0031,
443bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi    WAVE_FORMAT_EXTENSIBLE = 0xFFFE
4542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber};
460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
473bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivistatic const char* WAVEEXT_SUBFORMAT = "\x00\x00\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71";
483bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
493bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint32_t U32_LE_AT(const uint8_t *ptr) {
510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0];
520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint16_t U16_LE_AT(const uint8_t *ptr) {
550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return ptr[1] << 8 | ptr[0];
560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstruct WAVSource : public MediaSource {
590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    WAVSource(
600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            const sp<DataSource> &dataSource,
61f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            const sp<MetaData> &meta,
6242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            uint16_t waveFormat,
63f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            int32_t bitsPerSample,
64c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong            off64_t offset, size_t size);
650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual status_t start(MetaData *params = NULL);
670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual status_t stop();
680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual sp<MetaData> getFormat();
690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual status_t read(
710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            MediaBuffer **buffer, const ReadOptions *options = NULL);
720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprotected:
740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual ~WAVSource();
750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprivate:
770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    static const size_t kMaxFrameSize;
780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    sp<DataSource> mDataSource;
80f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    sp<MetaData> mMeta;
8142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber    uint16_t mWaveFormat;
820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    int32_t mSampleRate;
830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    int32_t mNumChannels;
84f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    int32_t mBitsPerSample;
85c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t mOffset;
860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    size_t mSize;
870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    bool mStarted;
880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    MediaBufferGroup *mGroup;
89c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t mCurrentPos;
900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    WAVSource(const WAVSource &);
920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    WAVSource &operator=(const WAVSource &);
930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber};
940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::WAVExtractor(const sp<DataSource> &source)
960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    : mDataSource(source),
973bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi      mValidFormat(false),
983bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi      mChannelMask(CHANNEL_MASK_USE_CHANNEL_ORDER) {
990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mInitCheck = init();
1000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
1010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::~WAVExtractor() {
1030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
1040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1057be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> WAVExtractor::getMetaData() {
1067be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    sp<MetaData> meta = new MetaData;
1077be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
1087be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    if (mInitCheck != OK) {
1097be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber        return meta;
1107be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    }
1117be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
11206096f955d486e229e19956052925f43f2f3f7c4Dongwon Kang    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_WAV);
1137be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
1147be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    return meta;
1157be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber}
1167be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
1170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersize_t WAVExtractor::countTracks() {
1180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return mInitCheck == OK ? 1 : 0;
1190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
1200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
121b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissensp<IMediaSource> WAVExtractor::getTrack(size_t index) {
1220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mInitCheck != OK || index > 0) {
1230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return NULL;
1240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
1250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return new WAVSource(
127f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            mDataSource, mTrackMeta,
12842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            mWaveFormat, mBitsPerSample, mDataOffset, mDataSize);
1290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
1300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVExtractor::getTrackMetaData(
13284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        size_t index, uint32_t /* flags */) {
1330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mInitCheck != OK || index > 0) {
1340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return NULL;
1350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
1360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
137f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    return mTrackMeta;
1380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
1390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVExtractor::init() {
1410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    uint8_t header[12];
1420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mDataSource->readAt(
1430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
1440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return NO_INIT;
1450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
1460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) {
1480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return NO_INIT;
1490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
1500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    size_t totalSize = U32_LE_AT(&header[4]);
1520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
153c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong    off64_t offset = 12;
1540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    size_t remainingSize = totalSize;
1550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    while (remainingSize >= 8) {
1560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        uint8_t chunkHeader[8];
1570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        if (mDataSource->readAt(offset, chunkHeader, 8) < 8) {
1580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            return NO_INIT;
1590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        }
1600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        remainingSize -= 8;
1620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        offset += 8;
163f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
1640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        uint32_t chunkSize = U32_LE_AT(&chunkHeader[4]);
1650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        if (chunkSize > remainingSize) {
1670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            return NO_INIT;
1680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        }
1690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        if (!memcmp(chunkHeader, "fmt ", 4)) {
1710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            if (chunkSize < 16) {
1720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return NO_INIT;
1730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
1740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1753bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            uint8_t formatSpec[40];
1763bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            if (mDataSource->readAt(offset, formatSpec, 2) < 2) {
1770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return NO_INIT;
1780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
1790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
18042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            mWaveFormat = U16_LE_AT(formatSpec);
18142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            if (mWaveFormat != WAVE_FORMAT_PCM
18275e6e22434d6fb3021738dcef644109374e75643Andy Hung                    && mWaveFormat != WAVE_FORMAT_IEEE_FLOAT
18342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    && mWaveFormat != WAVE_FORMAT_ALAW
1843bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    && mWaveFormat != WAVE_FORMAT_MULAW
185ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                    && mWaveFormat != WAVE_FORMAT_MSGSM
1863bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    && mWaveFormat != WAVE_FORMAT_EXTENSIBLE) {
1870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return ERROR_UNSUPPORTED;
1880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
1890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1903bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            uint8_t fmtSize = 16;
1913bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            if (mWaveFormat == WAVE_FORMAT_EXTENSIBLE) {
1923bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                fmtSize = 40;
1933bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            }
1943bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            if (mDataSource->readAt(offset, formatSpec, fmtSize) < fmtSize) {
1953bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                return NO_INIT;
1963bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            }
1973bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
1980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            mNumChannels = U16_LE_AT(&formatSpec[2]);
199778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz
200778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz            if (mNumChannels < 1 || mNumChannels > 8) {
201778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz                ALOGE("Unsupported number of channels (%d)", mNumChannels);
202778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz                return ERROR_UNSUPPORTED;
203778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz            }
204778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz
2053bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            if (mWaveFormat != WAVE_FORMAT_EXTENSIBLE) {
206778d09b607bd01888698c2110b05d3fc86c3b6ecNiel Alejandro Paz                if (mNumChannels != 1 && mNumChannels != 2) {
2073bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    ALOGW("More than 2 channels (%d) in non-WAVE_EXT, unknown channel mask",
2083bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                            mNumChannels);
2093bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
2100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
2110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            mSampleRate = U32_LE_AT(&formatSpec[4]);
2130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
214f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            if (mSampleRate == 0) {
215f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                return ERROR_MALFORMED;
216f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            }
217f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
218f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            mBitsPerSample = U16_LE_AT(&formatSpec[14]);
219f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
2203bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            if (mWaveFormat == WAVE_FORMAT_EXTENSIBLE) {
2213bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                uint16_t validBitsPerSample = U16_LE_AT(&formatSpec[18]);
2223bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                if (validBitsPerSample != mBitsPerSample) {
22306f6ae34c735640dccdaca6ab1567d8afc9d3938Jean-Michel Trivi                    if (validBitsPerSample != 0) {
22472b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                        ALOGE("validBits(%d) != bitsPerSample(%d) are not supported",
22572b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                                validBitsPerSample, mBitsPerSample);
22672b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                        return ERROR_UNSUPPORTED;
22772b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                    } else {
22872b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                        // we only support valitBitsPerSample == bitsPerSample but some WAV_EXT
22972b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                        // writers don't correctly set the valid bits value, and leave it at 0.
23072b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                        ALOGW("WAVE_EXT has 0 valid bits per sample, ignoring");
23172b2b9ba68ee85a3054a0de3a8414b8dfb217aebJean-Michel Trivi                    }
2323bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
2333bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
2343bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                mChannelMask = U32_LE_AT(&formatSpec[20]);
2353bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                ALOGV("numChannels=%d channelMask=0x%x", mNumChannels, mChannelMask);
2363bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                if ((mChannelMask >> 18) != 0) {
2373bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    ALOGE("invalid channel mask 0x%x", mChannelMask);
2383bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    return ERROR_MALFORMED;
2393bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
2403bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
2413bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                if ((mChannelMask != CHANNEL_MASK_USE_CHANNEL_ORDER)
2423bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                        && (popcount(mChannelMask) != mNumChannels)) {
2433bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    ALOGE("invalid number of channels (%d) in channel mask (0x%x)",
2443bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                            popcount(mChannelMask), mChannelMask);
2453bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    return ERROR_MALFORMED;
2463bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
2473bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
2483bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                // In a WAVE_EXT header, the first two bytes of the GUID stored at byte 24 contain
2493bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                // the sample format, using the same definitions as a regular WAV header
2503bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                mWaveFormat = U16_LE_AT(&formatSpec[24]);
2513bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                if (memcmp(&formatSpec[26], WAVEEXT_SUBFORMAT, 14)) {
2523bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    ALOGE("unsupported GUID");
2533bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                    return ERROR_UNSUPPORTED;
2543bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                }
2553bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi            }
2563bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi
25775e6e22434d6fb3021738dcef644109374e75643Andy Hung            if (mWaveFormat == WAVE_FORMAT_PCM) {
25875e6e22434d6fb3021738dcef644109374e75643Andy Hung                if (mBitsPerSample != 8 && mBitsPerSample != 16
25975e6e22434d6fb3021738dcef644109374e75643Andy Hung                    && mBitsPerSample != 24 && mBitsPerSample != 32) {
26075e6e22434d6fb3021738dcef644109374e75643Andy Hung                    return ERROR_UNSUPPORTED;
26175e6e22434d6fb3021738dcef644109374e75643Andy Hung                }
26275e6e22434d6fb3021738dcef644109374e75643Andy Hung            } else if (mWaveFormat == WAVE_FORMAT_IEEE_FLOAT) {
26375e6e22434d6fb3021738dcef644109374e75643Andy Hung                if (mBitsPerSample != 32) {  // TODO we don't support double
26475e6e22434d6fb3021738dcef644109374e75643Andy Hung                    return ERROR_UNSUPPORTED;
26575e6e22434d6fb3021738dcef644109374e75643Andy Hung                }
26675e6e22434d6fb3021738dcef644109374e75643Andy Hung            }
26775e6e22434d6fb3021738dcef644109374e75643Andy Hung            else if (mWaveFormat == WAVE_FORMAT_MSGSM) {
26875e6e22434d6fb3021738dcef644109374e75643Andy Hung                if (mBitsPerSample != 0) {
26975e6e22434d6fb3021738dcef644109374e75643Andy Hung                    return ERROR_UNSUPPORTED;
27075e6e22434d6fb3021738dcef644109374e75643Andy Hung                }
27175e6e22434d6fb3021738dcef644109374e75643Andy Hung            } else if (mWaveFormat == WAVE_FORMAT_MULAW || mWaveFormat == WAVE_FORMAT_ALAW) {
27275e6e22434d6fb3021738dcef644109374e75643Andy Hung                if (mBitsPerSample != 8) {
27375e6e22434d6fb3021738dcef644109374e75643Andy Hung                    return ERROR_UNSUPPORTED;
27475e6e22434d6fb3021738dcef644109374e75643Andy Hung                }
27575e6e22434d6fb3021738dcef644109374e75643Andy Hung            } else {
27675e6e22434d6fb3021738dcef644109374e75643Andy Hung                return ERROR_UNSUPPORTED;
27775e6e22434d6fb3021738dcef644109374e75643Andy Hung            }
27875e6e22434d6fb3021738dcef644109374e75643Andy Hung
2790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            mValidFormat = true;
2800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        } else if (!memcmp(chunkHeader, "data", 4)) {
2810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            if (mValidFormat) {
2820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                mDataOffset = offset;
2830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                mDataSize = chunkSize;
2840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
285f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta = new MetaData;
28642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
28742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                switch (mWaveFormat) {
28842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    case WAVE_FORMAT_PCM:
28975e6e22434d6fb3021738dcef644109374e75643Andy Hung                    case WAVE_FORMAT_IEEE_FLOAT:
29042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        mTrackMeta->setCString(
29142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
29242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        break;
29342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    case WAVE_FORMAT_ALAW:
29442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        mTrackMeta->setCString(
29542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_ALAW);
29642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        break;
297ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                    case WAVE_FORMAT_MSGSM:
298ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                        mTrackMeta->setCString(
299ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MSGSM);
300ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                        break;
30142d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                    default:
302f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong                        CHECK_EQ(mWaveFormat, (uint16_t)WAVE_FORMAT_MULAW);
30342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        mTrackMeta->setCString(
30442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_MLAW);
30542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                        break;
30642d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber                }
30742d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
308f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta->setInt32(kKeyChannelCount, mNumChannels);
3093bed68cb3d43af40475f56211869c40470c1fb4dJean-Michel Trivi                mTrackMeta->setInt32(kKeyChannelMask, mChannelMask);
310f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta->setInt32(kKeySampleRate, mSampleRate);
31178bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar                mTrackMeta->setInt32(kKeyPcmEncoding, kAudioEncodingPcm16bit);
312f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
313ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                int64_t durationUs = 0;
314ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                if (mWaveFormat == WAVE_FORMAT_MSGSM) {
315ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                    // 65 bytes decode to 320 8kHz samples
316ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                    durationUs =
317ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                        1000000LL * (mDataSize / 65 * 320) / 8000;
318ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                } else {
319ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                    size_t bytesPerSample = mBitsPerSample >> 3;
320e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake
321e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake                    if (!bytesPerSample || !mNumChannels)
322e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake                        return ERROR_MALFORMED;
323e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake
324e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake                    size_t num_samples = mDataSize / (mNumChannels * bytesPerSample);
325e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake
326e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake                    if (!mSampleRate)
327e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake                        return ERROR_MALFORMED;
328e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake
329ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                    durationUs =
330e52267adab4c89169aafd10a0fa2656ccb02c039Joshua J. Drake                        1000000LL * num_samples / mSampleRate;
331ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                }
332f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
333f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta->setInt64(kKeyDuration, durationUs);
334f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
3350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return OK;
3360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
3370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        }
3380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        offset += chunkSize;
3400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
3410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return NO_INIT;
3430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
3440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberconst size_t WAVSource::kMaxFrameSize = 32768;
3460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::WAVSource(
3480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        const sp<DataSource> &dataSource,
349f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        const sp<MetaData> &meta,
35042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber        uint16_t waveFormat,
351f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        int32_t bitsPerSample,
352c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t offset, size_t size)
3530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    : mDataSource(dataSource),
354f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mMeta(meta),
35542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber      mWaveFormat(waveFormat),
356f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mSampleRate(0),
357f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mNumChannels(0),
358f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mBitsPerSample(bitsPerSample),
3590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mOffset(offset),
3600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mSize(size),
3610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mStarted(false),
3620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mGroup(NULL) {
363f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    CHECK(mMeta->findInt32(kKeySampleRate, &mSampleRate));
364f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    CHECK(mMeta->findInt32(kKeyChannelCount, &mNumChannels));
365bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
366bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    mMeta->setInt32(kKeyMaxInputSize, kMaxFrameSize);
3670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
3680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::~WAVSource() {
3700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mStarted) {
3710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        stop();
3720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
3730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
3740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
37584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t WAVSource::start(MetaData * /* params */) {
3763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("WAVSource::start");
3770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    CHECK(!mStarted);
3790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mGroup = new MediaBufferGroup;
3810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
3820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
383f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    if (mBitsPerSample == 8) {
384f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        // As a temporary buffer for 8->16 bit conversion.
385f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
386f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    }
387f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
3880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mCurrentPos = mOffset;
3890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mStarted = true;
3910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return OK;
3930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
3940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::stop() {
3963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("WAVSource::stop");
3970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    CHECK(mStarted);
3990dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    delete mGroup;
4010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mGroup = NULL;
4020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mStarted = false;
4040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return OK;
4060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
4070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVSource::getFormat() {
4093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("WAVSource::getFormat");
4100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
411f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    return mMeta;
4120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
4130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::read(
4150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
4160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *out = NULL;
4170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    int64_t seekTimeUs;
419abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    ReadOptions::SeekMode mode;
420abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) {
421ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        int64_t pos = 0;
422ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen
423ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        if (mWaveFormat == WAVE_FORMAT_MSGSM) {
424ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            // 65 bytes decode to 320 8kHz samples
425ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            int64_t samplenumber = (seekTimeUs * mSampleRate) / 1000000;
426ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            int64_t framenumber = samplenumber / 320;
427ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            pos = framenumber * 65;
428ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        } else {
429ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            pos = (seekTimeUs * mSampleRate) / 1000000 * mNumChannels * (mBitsPerSample >> 3);
430ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        }
431a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn        if (pos > (off64_t)mSize) {
4320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            pos = mSize;
4330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        }
4340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        mCurrentPos = pos + mOffset;
4350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
4360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    MediaBuffer *buffer;
4380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    status_t err = mGroup->acquire_buffer(&buffer);
4390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (err != OK) {
4400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return err;
4410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
4420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4439b1797fed7065be05f8fb7a36d1a27e0df3cb7abcong.zhou    // make sure that maxBytesToRead is multiple of 3, in 24-bit case
444104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber    size_t maxBytesToRead =
4459b1797fed7065be05f8fb7a36d1a27e0df3cb7abcong.zhou        mBitsPerSample == 8 ? kMaxFrameSize / 2 :
4469b1797fed7065be05f8fb7a36d1a27e0df3cb7abcong.zhou        (mBitsPerSample == 24 ? 3*(kMaxFrameSize/3): kMaxFrameSize);
447104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber
448104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber    size_t maxBytesAvailable =
449c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        (mCurrentPos - mOffset >= (off64_t)mSize)
450104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber            ? 0 : mSize - (mCurrentPos - mOffset);
451104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber
452104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber    if (maxBytesToRead > maxBytesAvailable) {
453104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber        maxBytesToRead = maxBytesAvailable;
454104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber    }
455104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber
456ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen    if (mWaveFormat == WAVE_FORMAT_MSGSM) {
457ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        // Microsoft packs 2 frames into 65 bytes, rather than using separate 33-byte frames,
458ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        // so read multiples of 65, and use smaller buffers to account for ~10:1 expansion ratio
459ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        if (maxBytesToRead > 1024) {
460ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            maxBytesToRead = 1024;
461ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        }
462ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        maxBytesToRead = (maxBytesToRead / 65) * 65;
46341d3f579d2c166984958263533284209b90c87d5Marco Nelissen    } else {
46441d3f579d2c166984958263533284209b90c87d5Marco Nelissen        // read only integral amounts of audio unit frames.
46541d3f579d2c166984958263533284209b90c87d5Marco Nelissen        const size_t inputUnitFrameSize = mNumChannels * mBitsPerSample / 8;
46641d3f579d2c166984958263533284209b90c87d5Marco Nelissen        maxBytesToRead -= maxBytesToRead % inputUnitFrameSize;
467ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen    }
468ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen
4690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    ssize_t n = mDataSource->readAt(
470f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            mCurrentPos, buffer->data(),
471104fcb88d4125caff74f63be4ce23537ca693ac7Andreas Huber            maxBytesToRead);
4720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (n <= 0) {
4740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        buffer->release();
4750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        buffer = NULL;
4760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return ERROR_END_OF_STREAM;
4780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
4790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
4800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    buffer->set_range(0, n);
481f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
48275e6e22434d6fb3021738dcef644109374e75643Andy Hung    // TODO: add capability to return data as float PCM instead of 16 bit PCM.
48375e6e22434d6fb3021738dcef644109374e75643Andy Hung    if (mWaveFormat == WAVE_FORMAT_PCM) {
48442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber        if (mBitsPerSample == 8) {
48542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            // Convert 8-bit unsigned samples to 16-bit signed.
486f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
48775e6e22434d6fb3021738dcef644109374e75643Andy Hung            // Create new buffer with 2 byte wide samples
48842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            MediaBuffer *tmp;
489f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong            CHECK_EQ(mGroup->acquire_buffer(&tmp), (status_t)OK);
49042d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            tmp->set_range(0, 2 * n);
491f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
49275e6e22434d6fb3021738dcef644109374e75643Andy Hung            memcpy_to_i16_from_u8((int16_t *)tmp->data(), (const uint8_t *)buffer->data(), n);
49342d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            buffer->release();
49442d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber            buffer = tmp;
49542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber        } else if (mBitsPerSample == 24) {
49675e6e22434d6fb3021738dcef644109374e75643Andy Hung            // Convert 24-bit signed samples to 16-bit signed in place
49775e6e22434d6fb3021738dcef644109374e75643Andy Hung            const size_t numSamples = n / 3;
49842d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
49975e6e22434d6fb3021738dcef644109374e75643Andy Hung            memcpy_to_i16_from_p24((int16_t *)buffer->data(), (const uint8_t *)buffer->data(), numSamples);
50075e6e22434d6fb3021738dcef644109374e75643Andy Hung            buffer->set_range(0, 2 * numSamples);
50175e6e22434d6fb3021738dcef644109374e75643Andy Hung        }  else if (mBitsPerSample == 32) {
50275e6e22434d6fb3021738dcef644109374e75643Andy Hung            // Convert 32-bit signed samples to 16-bit signed in place
50375e6e22434d6fb3021738dcef644109374e75643Andy Hung            const size_t numSamples = n / 4;
504984d8f40c15e7fd757a9fdc007aad75549aa0fceAndreas Huber
50575e6e22434d6fb3021738dcef644109374e75643Andy Hung            memcpy_to_i16_from_i32((int16_t *)buffer->data(), (const int32_t *)buffer->data(), numSamples);
50675e6e22434d6fb3021738dcef644109374e75643Andy Hung            buffer->set_range(0, 2 * numSamples);
50775e6e22434d6fb3021738dcef644109374e75643Andy Hung        }
50875e6e22434d6fb3021738dcef644109374e75643Andy Hung    } else if (mWaveFormat == WAVE_FORMAT_IEEE_FLOAT) {
50975e6e22434d6fb3021738dcef644109374e75643Andy Hung        if (mBitsPerSample == 32) {
51075e6e22434d6fb3021738dcef644109374e75643Andy Hung            // Convert 32-bit float samples to 16-bit signed in place
51175e6e22434d6fb3021738dcef644109374e75643Andy Hung            const size_t numSamples = n / 4;
51242d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber
51375e6e22434d6fb3021738dcef644109374e75643Andy Hung            memcpy_to_i16_from_float((int16_t *)buffer->data(), (const float *)buffer->data(), numSamples);
51475e6e22434d6fb3021738dcef644109374e75643Andy Hung            buffer->set_range(0, 2 * numSamples);
51542d66f25af9cb8089a93c6796876a6bc16e36ceaAndreas Huber        }
516f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    }
517f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
518ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen    int64_t timeStampUs = 0;
519ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen
520ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen    if (mWaveFormat == WAVE_FORMAT_MSGSM) {
521ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        timeStampUs = 1000000LL * (mCurrentPos - mOffset) * 320 / 65 / mSampleRate;
522ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen    } else {
523ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        size_t bytesPerSample = mBitsPerSample >> 3;
524ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        timeStampUs = 1000000LL * (mCurrentPos - mOffset)
525ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen                / (mNumChannels * bytesPerSample) / mSampleRate;
526ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen    }
527f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
528ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen    buffer->meta_data()->setInt64(kKeyTime, timeStampUs);
5290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
5308bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
531f1e10e8ed74cac805d601139882378a1f450fe94James Dong    mCurrentPos += n;
5320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
5330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *out = buffer;
5340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
5350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return OK;
5360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
5370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
5380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber////////////////////////////////////////////////////////////////////////////////
5390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
5400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberbool SniffWAV(
5415a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence,
5425a1c3529e4fa2f8a11054181294e0ce79fff8dd3Andreas Huber        sp<AMessage> *) {
5430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    char header[12];
5440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
5450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return false;
5460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
5470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
5480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) {
5490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return false;
5500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
5510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
55270d3e260edcd42972864bf501337f0b1a187657dJames Dong    sp<MediaExtractor> extractor = new WAVExtractor(source);
55370d3e260edcd42972864bf501337f0b1a187657dJames Dong    if (extractor->countTracks() == 0) {
55470d3e260edcd42972864bf501337f0b1a187657dJames Dong        return false;
55570d3e260edcd42972864bf501337f0b1a187657dJames Dong    }
55670d3e260edcd42972864bf501337f0b1a187657dJames Dong
5570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *mimeType = MEDIA_MIMETYPE_CONTAINER_WAV;
5580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *confidence = 0.3f;
5590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
5600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return true;
5610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
5620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
5630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}  // namespace android
564