WAVExtractor.cpp revision f99f049dd228333e3d6f886efe373f8e461ff2da
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
230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/DataSource.h>
240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaBufferGroup.h>
250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaDebug.h>
260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaDefs.h>
270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaErrors.h>
280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MediaSource.h>
290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <media/stagefright/MetaData.h>
300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber#include <utils/String8.h>
310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubernamespace android {
330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint16_t WAVE_FORMAT_PCM = 1;
350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint32_t U32_LE_AT(const uint8_t *ptr) {
370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0];
380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatic uint16_t U16_LE_AT(const uint8_t *ptr) {
410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return ptr[1] << 8 | ptr[0];
420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstruct WAVSource : public MediaSource {
450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    WAVSource(
460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            const sp<DataSource> &dataSource,
47f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            const sp<MetaData> &meta,
48f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            int32_t bitsPerSample,
490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            off_t offset, size_t size);
500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual status_t start(MetaData *params = NULL);
520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual status_t stop();
530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual sp<MetaData> getFormat();
540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual status_t read(
560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            MediaBuffer **buffer, const ReadOptions *options = NULL);
570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprotected:
590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    virtual ~WAVSource();
600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberprivate:
620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    static const size_t kMaxFrameSize;
630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    sp<DataSource> mDataSource;
65f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    sp<MetaData> mMeta;
660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    int32_t mSampleRate;
670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    int32_t mNumChannels;
68f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    int32_t mBitsPerSample;
690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    off_t mOffset;
700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    size_t mSize;
710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    bool mStarted;
720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    MediaBufferGroup *mGroup;
730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    off_t mCurrentPos;
740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    WAVSource(const WAVSource &);
760dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    WAVSource &operator=(const WAVSource &);
770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber};
780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::WAVExtractor(const sp<DataSource> &source)
800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    : mDataSource(source),
810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mValidFormat(false) {
820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mInitCheck = init();
830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVExtractor::~WAVExtractor() {
860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
887be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> WAVExtractor::getMetaData() {
897be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    sp<MetaData> meta = new MetaData;
907be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
917be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    if (mInitCheck != OK) {
927be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber        return meta;
937be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    }
947be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
957be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    meta->setCString(kKeyMIMEType, "audio/x-wav");
967be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
977be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber    return meta;
987be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber}
997be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber
1000dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersize_t WAVExtractor::countTracks() {
1010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return mInitCheck == OK ? 1 : 0;
1020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
1030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MediaSource> WAVExtractor::getTrack(size_t index) {
1050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mInitCheck != OK || index > 0) {
1060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return NULL;
1070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
1080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return new WAVSource(
110f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            mDataSource, mTrackMeta,
111f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            mBitsPerSample, mDataOffset, mDataSize);
1120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
1130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVExtractor::getTrackMetaData(
1150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        size_t index, uint32_t flags) {
1160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mInitCheck != OK || index > 0) {
1170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return NULL;
1180dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
1190dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
120f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    return mTrackMeta;
1210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
1220dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1230dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVExtractor::init() {
1240dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    uint8_t header[12];
1250dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mDataSource->readAt(
1260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
1270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return NO_INIT;
1280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
1290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1300dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) {
1310dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return NO_INIT;
1320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
1330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    size_t totalSize = U32_LE_AT(&header[4]);
1350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    off_t offset = 12;
1370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    size_t remainingSize = totalSize;
1380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    while (remainingSize >= 8) {
1390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        uint8_t chunkHeader[8];
1400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        if (mDataSource->readAt(offset, chunkHeader, 8) < 8) {
1410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            return NO_INIT;
1420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        }
1430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        remainingSize -= 8;
1450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        offset += 8;
146f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
1470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        uint32_t chunkSize = U32_LE_AT(&chunkHeader[4]);
1480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        if (chunkSize > remainingSize) {
1500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            return NO_INIT;
1510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        }
1520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        if (!memcmp(chunkHeader, "fmt ", 4)) {
1540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            if (chunkSize < 16) {
1550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return NO_INIT;
1560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
1570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            uint8_t formatSpec[16];
1590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            if (mDataSource->readAt(offset, formatSpec, 16) < 16) {
1600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return NO_INIT;
1610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
1620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            uint16_t format = U16_LE_AT(formatSpec);
1640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            if (format != WAVE_FORMAT_PCM) {
1650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return ERROR_UNSUPPORTED;
1660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
1670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            mNumChannels = U16_LE_AT(&formatSpec[2]);
1690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            if (mNumChannels != 1 && mNumChannels != 2) {
1700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return ERROR_UNSUPPORTED;
1710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
1720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            mSampleRate = U32_LE_AT(&formatSpec[4]);
1740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
175f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            if (mSampleRate == 0) {
176f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                return ERROR_MALFORMED;
177f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            }
178f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
179f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            mBitsPerSample = U16_LE_AT(&formatSpec[14]);
180f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
181f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            if (mBitsPerSample != 8 && mBitsPerSample != 16) {
1820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return ERROR_UNSUPPORTED;
1830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
1840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
1850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            mValidFormat = true;
1860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        } else if (!memcmp(chunkHeader, "data", 4)) {
1870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            if (mValidFormat) {
1880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                mDataOffset = offset;
1890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                mDataSize = chunkSize;
1900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
191f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta = new MetaData;
192f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
193f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta->setInt32(kKeyChannelCount, mNumChannels);
194f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta->setInt32(kKeySampleRate, mSampleRate);
195f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
196f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                size_t bytesPerSample = mBitsPerSample >> 3;
197f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
198f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                int64_t durationUs =
199f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                    1000000LL * (mDataSize / (mNumChannels * bytesPerSample))
200f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                        / mSampleRate;
201f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
202f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                mTrackMeta->setInt64(kKeyDuration, durationUs);
203f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
2040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber                return OK;
2050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            }
2060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        }
2070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        offset += chunkSize;
2090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
2100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return NO_INIT;
2120dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
2130dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2140dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberconst size_t WAVSource::kMaxFrameSize = 32768;
2150dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2160dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::WAVSource(
2170dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        const sp<DataSource> &dataSource,
218f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        const sp<MetaData> &meta,
219f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        int32_t bitsPerSample,
2200dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        off_t offset, size_t size)
2210dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    : mDataSource(dataSource),
222f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mMeta(meta),
223f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mSampleRate(0),
224f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mNumChannels(0),
225f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber      mBitsPerSample(bitsPerSample),
2260dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mOffset(offset),
2270dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mSize(size),
2280dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mStarted(false),
2290dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber      mGroup(NULL) {
230f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    CHECK(mMeta->findInt32(kKeySampleRate, &mSampleRate));
231f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    CHECK(mMeta->findInt32(kKeyChannelCount, &mNumChannels));
2320dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
2330dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2340dba73763a04d39faf999dcc5ef12af3c99535a7Andreas HuberWAVSource::~WAVSource() {
2350dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (mStarted) {
2360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        stop();
2370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
2380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
2390dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::start(MetaData *params) {
2410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    LOGV("WAVSource::start");
2420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    CHECK(!mStarted);
2440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mGroup = new MediaBufferGroup;
2460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
2470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
248f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    if (mBitsPerSample == 8) {
249f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        // As a temporary buffer for 8->16 bit conversion.
250f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
251f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    }
252f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
2530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mCurrentPos = mOffset;
2540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mStarted = true;
2560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return OK;
2580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
2590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::stop() {
2610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    LOGV("WAVSource::stop");
2620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    CHECK(mStarted);
2640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    delete mGroup;
2660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mGroup = NULL;
2670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2680dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mStarted = false;
2690dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2700dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return OK;
2710dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
2720dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2730dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Hubersp<MetaData> WAVSource::getFormat() {
2740dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    LOGV("WAVSource::getFormat");
2750dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
276f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    return mMeta;
2770dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
2780dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2790dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberstatus_t WAVSource::read(
2800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
2810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *out = NULL;
2820dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2830dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    int64_t seekTimeUs;
2840dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (options != NULL && options->getSeekTo(&seekTimeUs)) {
2850dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        int64_t pos = (seekTimeUs * mSampleRate) / 1000000 * mNumChannels * 2;
2860dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        if (pos > mSize) {
2870dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            pos = mSize;
2880dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        }
2890dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        mCurrentPos = pos + mOffset;
2900dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
2910dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2920dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    MediaBuffer *buffer;
2930dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    status_t err = mGroup->acquire_buffer(&buffer);
2940dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (err != OK) {
2950dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return err;
2960dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
2970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
2980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    ssize_t n = mDataSource->readAt(
299f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            mCurrentPos, buffer->data(),
300f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            mBitsPerSample == 8 ? kMaxFrameSize / 2 : kMaxFrameSize);
3010dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3020dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (n <= 0) {
3030dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        buffer->release();
3040dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        buffer = NULL;
3050dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3060dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return ERROR_END_OF_STREAM;
3070dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
3080dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3090dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    mCurrentPos += n;
3100dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3110dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    buffer->set_range(0, n);
312f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
313f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    if (mBitsPerSample == 8) {
314f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        // Convert 8-bit unsigned samples to 16-bit signed.
315f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
316f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        MediaBuffer *tmp;
317f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        CHECK_EQ(mGroup->acquire_buffer(&tmp), OK);
318f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
319f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        // The new buffer holds the sample number of samples, but each
320f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        // one is 2 bytes wide.
321f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        tmp->set_range(0, 2 * n);
322f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
323f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        int16_t *dst = (int16_t *)tmp->data();
324f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        const uint8_t *src = (const uint8_t *)buffer->data();
325f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        while (n-- > 0) {
326f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            *dst++ = ((int16_t)(*src) - 128) * 256;
327f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber            ++src;
328f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        }
329f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
330f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        buffer->release();
331f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber        buffer = tmp;
332f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    }
333f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
334f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber    size_t bytesPerSample = mBitsPerSample >> 3;
335f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber
3360dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    buffer->meta_data()->setInt64(
3370dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            kKeyTime,
3380dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber            1000000LL * (mCurrentPos - mOffset)
339f99f049dd228333e3d6f886efe373f8e461ff2daAndreas Huber                / (mNumChannels * bytesPerSample) / mSampleRate);
3400dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3410dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3420dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *out = buffer;
3430dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3440dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return OK;
3450dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
3460dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3470dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber////////////////////////////////////////////////////////////////////////////////
3480dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3490dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huberbool SniffWAV(
3500dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
3510dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    char header[12];
3520dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (source->readAt(0, header, sizeof(header)) < (ssize_t)sizeof(header)) {
3530dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return false;
3540dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
3550dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3560dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    if (memcmp(header, "RIFF", 4) || memcmp(&header[8], "WAVE", 4)) {
3570dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber        return false;
3580dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    }
3590dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3600dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *mimeType = MEDIA_MIMETYPE_CONTAINER_WAV;
3610dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    *confidence = 0.3f;
3620dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3630dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber    return true;
3640dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}
3650dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
3660dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber}  // namespace android
3670dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber
368