SndFile.c revision b7154f2324c8ae44b820c07c69aaa80a4bb9e418
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
23b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten#include "SndFile.h"
24b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten
25b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten// FIXME should run this asynchronously esp. for socket fd, not on mix thread
26b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kastenvoid SLAPIENTRY SndFile_Callback(SLBufferQueueItf caller, void *pContext)
27b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten{
28b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    struct SndFile *this = (struct SndFile *) pContext;
29b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    SLresult result;
30b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    if (NULL != this->mRetryBuffer && 0 < this->mRetrySize) {
31b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        result = (*caller)->Enqueue(caller, this->mRetryBuffer,
32b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten            this->mRetrySize);
33b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        if (SL_RESULT_BUFFER_INSUFFICIENT == result)
34b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten            return;     // what, again?
35b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
36b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        this->mRetryBuffer = NULL;
37b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        this->mRetrySize = 0;
38b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        return;
39b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    }
40b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    short *pBuffer = this->mIs0 ? this->mBuffer0 : this->mBuffer1;
41b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    this->mIs0 ^= SL_BOOLEAN_TRUE;
42b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    sf_count_t count;
43b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    // FIXME magic number
44b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    count = sf_read_short(this->mSNDFILE, pBuffer, (sf_count_t) 512);
45b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    if (0 < count) {
46b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        SLuint32 size = count * sizeof(short);
47b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        // FIXME if we had an internal API, could call this directly
48b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        result = (*caller)->Enqueue(caller, pBuffer, size);
49b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        if (SL_RESULT_BUFFER_INSUFFICIENT == result) {
50b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten            this->mRetryBuffer = pBuffer;
51b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten            this->mRetrySize = size;
52b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten            return;
53b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        }
54b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        assert(SL_RESULT_SUCCESS == result);
55b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    }
56b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten}
57b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten
58b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn KastenSLboolean SndFile_IsSupported(const SF_INFO *sfinfo)
59b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten{
60b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    switch (sfinfo->format & SF_FORMAT_TYPEMASK) {
61b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    case SF_FORMAT_WAV:
62b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        break;
63b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    default:
64b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        return SL_BOOLEAN_FALSE;
65b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    }
66b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    switch (sfinfo->format & SF_FORMAT_SUBMASK) {
67b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    case SF_FORMAT_PCM_16:
68b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        break;
69b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    default:
70b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        return SL_BOOLEAN_FALSE;
71b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    }
72b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    switch (sfinfo->samplerate) {
73b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    case 44100:
74b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        break;
75b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    default:
76b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        return SL_BOOLEAN_FALSE;
77b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    }
78b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    switch (sfinfo->channels) {
79b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    case 2:
80b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        break;
81b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    default:
82b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten        return SL_BOOLEAN_FALSE;
83b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    }
84b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    return SL_BOOLEAN_TRUE;
85b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten}
86b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten
87b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten#endif // USE_SNDFILE
88