SndFile.c revision 276cab2d983b892d1b634474b6249f6bec400c76
1b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten/*
2b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * Copyright (C) 2010 The Android Open Source Project
3b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten *
4b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
5b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * you may not use this file except in compliance with the License.
6b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * You may obtain a copy of the License at
7b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten *
8b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
9b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten *
10b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * Unless required by applicable law or agreed to in writing, software
11b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
12b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * See the License for the specific language governing permissions and
14b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten * limitations under the License.
15b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten */
16b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten
17b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten/* libsndfile integration */
18b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten
19b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten#include "sles_allinclusive.h"
20b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten
21b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten#ifdef USE_SNDFILE
22b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten
23276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten// FIXME Needs some mutexes here and there
24276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten
25b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten// FIXME should run this asynchronously esp. for socket fd, not on mix thread
267324a5ab12cc734e2feb4cef8baeda26566d3c92Glenn Kastenvoid /*SLAPIENTRY*/ SndFile_Callback(SLBufferQueueItf caller, void *pContext)
27b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten{
28276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten    CAudioPlayer *thisAP = (CAudioPlayer *) pContext;
29276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten    if (thisAP->mPlay.mState != SL_PLAYSTATE_PLAYING)
30276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten        return;
31276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten    struct SndFile *this = &thisAP->mSndFile;
32b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    SLresult result;
33b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    if (NULL != this->mRetryBuffer && 0 < this->mRetrySize) {
3427f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten        result = (*caller)->Enqueue(caller, this->mRetryBuffer, this->mRetrySize);
35b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        if (SL_RESULT_BUFFER_INSUFFICIENT == result)
36b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten            return;     // what, again?
37b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
38b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        this->mRetryBuffer = NULL;
39b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        this->mRetrySize = 0;
40b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        return;
41b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    }
42b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    short *pBuffer = this->mIs0 ? this->mBuffer0 : this->mBuffer1;
43b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    this->mIs0 ^= SL_BOOLEAN_TRUE;
44b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    sf_count_t count;
45b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    // FIXME magic number
46b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    count = sf_read_short(this->mSNDFILE, pBuffer, (sf_count_t) 512);
47b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    if (0 < count) {
487324a5ab12cc734e2feb4cef8baeda26566d3c92Glenn Kasten        SLuint32 size = (SLuint32) (count * sizeof(short));
49b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        // FIXME if we had an internal API, could call this directly
50b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        result = (*caller)->Enqueue(caller, pBuffer, size);
51b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        if (SL_RESULT_BUFFER_INSUFFICIENT == result) {
52b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten            this->mRetryBuffer = pBuffer;
53b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten            this->mRetrySize = size;
54b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten            return;
55b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        }
56b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
57276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten    } else {
58276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten        thisAP->mPlay.mState = SL_PLAYSTATE_PAUSED;
59276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten        (void) sf_seek(this->mSNDFILE, (sf_count_t) 0, SEEK_SET);
60b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    }
61b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten}
62b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten
63b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn KastenSLboolean SndFile_IsSupported(const SF_INFO *sfinfo)
64b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten{
65b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    switch (sfinfo->format & SF_FORMAT_TYPEMASK) {
66b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    case SF_FORMAT_WAV:
67b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        break;
68b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    default:
69b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        return SL_BOOLEAN_FALSE;
70b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    }
71b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    switch (sfinfo->format & SF_FORMAT_SUBMASK) {
72276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten    case SF_FORMAT_PCM_U8:
73b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    case SF_FORMAT_PCM_16:
74b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        break;
75b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    default:
76b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        return SL_BOOLEAN_FALSE;
77b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    }
78b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    switch (sfinfo->samplerate) {
79276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten    case 11025:
80276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten    case 22050:
81b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    case 44100:
82b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        break;
83b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    default:
84b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        return SL_BOOLEAN_FALSE;
85b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    }
86b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    switch (sfinfo->channels) {
87276cab2d983b892d1b634474b6249f6bec400c76Glenn Kasten    case 1:
88b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    case 2:
89b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        break;
90b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    default:
91b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        return SL_BOOLEAN_FALSE;
92b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    }
93b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    return SL_BOOLEAN_TRUE;
94b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten}
95b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten
96acd88797a1d3b8225bab888d29036e245f275be5Glenn KastenSLresult SndFile_checkAudioPlayerSourceSink(CAudioPlayer *this)
97daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten{
98acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten    const SLDataSource *pAudioSrc = &this->mDataSource.u.mSource;
99acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten    //const SLDataSink *pAudioSnk = &this->mDataSink.u.mSink;
100daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten    SLuint32 locatorType = *(SLuint32 *)pAudioSrc->pLocator;
101daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten    SLuint32 formatType = *(SLuint32 *)pAudioSrc->pFormat;
102daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten    switch (locatorType) {
103daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten    case SL_DATALOCATOR_BUFFERQUEUE:
104acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten        this->mBufferQueue.mNumBuffers =
105acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten            ((SLDataLocator_BufferQueue *) pAudioSrc->pLocator)->numBuffers;
106daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten        break;
107daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten    case SL_DATALOCATOR_URI:
108daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten        {
109daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten        SLDataLocator_URI *dl_uri = (SLDataLocator_URI *) pAudioSrc->pLocator;
110daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten        SLchar *uri = dl_uri->URI;
111daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten        if (NULL == uri)
112daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten            return SL_RESULT_PARAMETER_INVALID;
11327f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten        // FIXME check other schemes and handle, or return SL_RESULT_CONTENT_UNSUPPORTED
11427f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten        if (!strncmp((const char *) uri, "file:///", 8))
11527f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten            uri += 8;
116daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten        switch (formatType) {
117daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten        case SL_DATAFORMAT_MIME:
118daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten            break;
119daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten        default:
120daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten            return SL_RESULT_CONTENT_UNSUPPORTED;
121daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten        }
12227f8dfaea17ab7831a1bd34a02f85d55bacf67b7Glenn Kasten        this->mSndFile.mPathname = uri;
123daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten        // FIXME magic number, should be configurable
124acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten        this->mBufferQueue.mNumBuffers = 2;
125daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten        }
126daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten        break;
127daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten    default:
128daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten        return SL_RESULT_CONTENT_UNSUPPORTED;
129daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten    }
130acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten    this->mSndFile.mIs0 = SL_BOOLEAN_TRUE;
131acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten    this->mSndFile.mSNDFILE = NULL;
132acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten    this->mSndFile.mRetryBuffer = NULL;
133acd88797a1d3b8225bab888d29036e245f275be5Glenn Kasten    this->mSndFile.mRetrySize = 0;
134daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten    return SL_RESULT_SUCCESS;
135daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten}
136daf661248ff6ea2e21799e5114c78b7c1d49630eGlenn Kasten
137b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten#endif // USE_SNDFILE
138