1cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten/*
2cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten * Copyright (C) 2010 The Android Open Source Project
3cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten *
4cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
5cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten * you may not use this file except in compliance with the License.
6cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten * You may obtain a copy of the License at
7cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten *
8cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
9cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten *
10cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten * Unless required by applicable law or agreed to in writing, software
11cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
12cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten * See the License for the specific language governing permissions and
14cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten * limitations under the License.
15cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten */
16cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
17cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten// Test various buffer queue configurations
18cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
19cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten#include <assert.h>
209a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten#include <math.h>
21cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten#include <stdio.h>
22cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten#include <stdlib.h>
234d7c8c742d5b09895e7ce3d07d314b6ada56123dGlenn Kasten#include <unistd.h>
24cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
25a6c5e52ded343b557152156c33d33a10d29bf6f1Glenn Kasten#include <SLES/OpenSLES.h>
26cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
27cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kastentypedef struct {
28cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    SLuint8 numChannels;
29cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    SLuint32 milliHz;
30cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    SLuint8 bitsPerSample;
31cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten} PCM;
32cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
33cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn KastenPCM formats[] = {
34cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {1, SL_SAMPLINGRATE_8,      8},
35cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {2, SL_SAMPLINGRATE_8,      8},
36cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {1, SL_SAMPLINGRATE_8,      16},
37cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {2, SL_SAMPLINGRATE_8,      16},
38cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {1, SL_SAMPLINGRATE_11_025, 8},
39cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {2, SL_SAMPLINGRATE_11_025, 8},
40cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {1, SL_SAMPLINGRATE_11_025, 16},
41cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {2, SL_SAMPLINGRATE_11_025, 16},
42cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {1, SL_SAMPLINGRATE_12,     8},
43cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {2, SL_SAMPLINGRATE_12,     8},
44cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {1, SL_SAMPLINGRATE_12,     16},
45cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {2, SL_SAMPLINGRATE_12,     16},
46cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {1, SL_SAMPLINGRATE_16,     8},
47cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {2, SL_SAMPLINGRATE_16,     8},
48cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {1, SL_SAMPLINGRATE_16,     16},
49cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {2, SL_SAMPLINGRATE_16,     16},
50cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {1, SL_SAMPLINGRATE_22_05,  8},
51cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {2, SL_SAMPLINGRATE_22_05,  8},
52cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {1, SL_SAMPLINGRATE_22_05,  16},
53cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {2, SL_SAMPLINGRATE_22_05,  16},
54cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {1, SL_SAMPLINGRATE_24,     8},
55cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {2, SL_SAMPLINGRATE_24,     8},
56cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {1, SL_SAMPLINGRATE_24,     16},
57cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {2, SL_SAMPLINGRATE_24,     16},
58cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {1, SL_SAMPLINGRATE_32,     8},
59cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {2, SL_SAMPLINGRATE_32,     8},
60cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {1, SL_SAMPLINGRATE_32,     16},
61cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {2, SL_SAMPLINGRATE_32,     16},
62cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {1, SL_SAMPLINGRATE_44_1,   8},
63cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {2, SL_SAMPLINGRATE_44_1,   8},
64cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {1, SL_SAMPLINGRATE_44_1,   16},
65cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {2, SL_SAMPLINGRATE_44_1,   16},
66cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {1, SL_SAMPLINGRATE_48,     8},
67cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {2, SL_SAMPLINGRATE_48,     8},
68cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {1, SL_SAMPLINGRATE_48,     16},
69cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {2, SL_SAMPLINGRATE_48,     16},
70cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    {0, 0,                      0}
71cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten};
72cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
73cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kastenint main(int argc, char **argv)
74cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten{
75cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    SLresult result;
76cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    SLObjectItf engineObject;
77cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
78cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    // create engine
79cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
80cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    assert(SL_RESULT_SUCCESS == result);
81cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    SLEngineItf engineEngine;
82cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
83cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    assert(SL_RESULT_SUCCESS == result);
84cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
85cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    assert(SL_RESULT_SUCCESS == result);
86cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
87cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    // create output mix
88cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    SLObjectItf outputMixObject;
89cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL);
90cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    assert(SL_RESULT_SUCCESS == result);
91cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
92cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    assert(SL_RESULT_SUCCESS == result);
93cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
94cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    // loop over all formats
95cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    PCM *format;
969a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten    float hzLeft = 440.0;   // A440 (Concert A)
979a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten    float hzRight = 440.0;
98cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    for (format = formats; format->numChannels; ++format) {
99cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
100d968dacf7a35d52b6907283f3d95295a238340ccGlenn Kasten        printf("Channels: %d, sample rate: %u, bits: %u\n", format->numChannels,
101cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten                format->milliHz / 1000, format->bitsPerSample);
102cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
103cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        // configure audio source
104cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        SLDataLocator_BufferQueue loc_bufq;
105cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        loc_bufq.locatorType = SL_DATALOCATOR_BUFFERQUEUE;
106cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        loc_bufq.numBuffers = 1;
107cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        SLDataFormat_PCM format_pcm;
108cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        format_pcm.formatType = SL_DATAFORMAT_PCM;
109cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        format_pcm.numChannels = format->numChannels;
110cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        format_pcm.samplesPerSec = format->milliHz;
111cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        format_pcm.bitsPerSample = format->bitsPerSample;
112cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        format_pcm.containerSize = format->bitsPerSample;
113cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        format_pcm.channelMask = 0;
114cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
115cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        SLDataSource audioSrc;
116cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        audioSrc.pLocator = &loc_bufq;
117cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        audioSrc.pFormat = &format_pcm;
118cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
119cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        // configure audio sink
120cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        SLDataLocator_OutputMix loc_outmix;
121cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
122cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        loc_outmix.outputMix = outputMixObject;
123cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        SLDataSink audioSnk;
124cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        audioSnk.pLocator = &loc_outmix;
125cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        audioSnk.pFormat = NULL;
126cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
127cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        // create audio player
128cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        SLuint32 numInterfaces = 1;
129cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        SLInterfaceID ids[1];
130cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        SLboolean req[1];
131cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        ids[0] = SL_IID_BUFFERQUEUE;
132cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        req[0] = SL_BOOLEAN_TRUE;
133cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        SLObjectItf playerObject;
134cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        result = (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audioSrc,
135cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten                &audioSnk, numInterfaces, ids, req);
136cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        if (SL_RESULT_SUCCESS != result) {
137d968dacf7a35d52b6907283f3d95295a238340ccGlenn Kasten            printf("failed %u\n", result);
138cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten            continue;
139cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        }
140cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
141cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        // realize the player
142cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        result = (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE);
143cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        assert(SL_RESULT_SUCCESS == result);
144cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
1459a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten        // generate a sine wave buffer, ascending in half-steps for each format
1469a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten#define N (44100*4)
1479a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten        static unsigned char buffer[N];
148cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        unsigned i;
149cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        for (i = 0; i < N; ) {
1509a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten            float seconds = (((i * 8) / (format->bitsPerSample * format->numChannels)) * 1000.0) /
1519a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten                    format->milliHz;
1529a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten            short sampleLeft = sin(seconds * M_PI_2 * hzLeft) * 32767.0;
1539a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten            short sampleRight = sin(seconds * M_PI_2 * hzRight) * 32767.0;
154cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten            if (2 == format->numChannels) {
155cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten                if (8 == format->bitsPerSample) {
156cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten                    buffer[i++] = (sampleLeft + 32768) >> 8;
157cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten                    buffer[i++] = (sampleRight + 32768) >> 8;
158cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten                } else {
159cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten                    assert(16 == format->bitsPerSample);
1609a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten                    buffer[i++] = sampleLeft & 0xFF;
161cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten                    buffer[i++] = sampleLeft >> 8;
1629a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten                    buffer[i++] = sampleRight & 0xFF;
163cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten                    buffer[i++] = sampleRight >> 8;
164cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten                }
165cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten            } else {
166cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten                assert(1 == format->numChannels);
1679a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten                // cast to int and divide by 2 are needed to prevent overflow
1689a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten                short sampleMono = ((int) sampleLeft + (int) sampleRight) / 2;
169cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten                if (8 == format->bitsPerSample) {
1709a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten                    buffer[i++] = (sampleMono + 32768) >> 8;
171cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten                } else {
172cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten                    assert(16 == format->bitsPerSample);
1739a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten                    buffer[i++] = sampleMono & 0xFF;
1749a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten                    buffer[i++] = sampleMono >> 8;
175cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten                }
176cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten            }
1779a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten            if (seconds >= 1.0f)
1789a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten                break;
179cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        }
180cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
181cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        // get the buffer queue interface and enqueue a buffer
182cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        SLBufferQueueItf playerBufferQueue;
183cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        result = (*playerObject)->GetInterface(playerObject, SL_IID_BUFFERQUEUE,
184cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten                &playerBufferQueue);
185cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        assert(SL_RESULT_SUCCESS == result);
1869a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten        result = (*playerBufferQueue)->Enqueue(playerBufferQueue, buffer, i);
187cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        assert(SL_RESULT_SUCCESS == result);
188cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
189cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        // get the play interface
190cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        SLPlayItf playerPlay;
191cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        result = (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay);
192cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        assert(SL_RESULT_SUCCESS == result);
193cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
194cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        // set the player's state to playing
195cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING);
196cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        assert(SL_RESULT_SUCCESS == result);
197cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
198cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        // wait for the buffer to be played
199cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        for (;;) {
200cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten            SLBufferQueueState state;
201cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten            result = (*playerBufferQueue)->GetState(playerBufferQueue, &state);
202cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten            assert(SL_RESULT_SUCCESS == result);
203cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten            if (state.count == 0)
204cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten                break;
205cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten            usleep(20000);
206cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        }
207cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
208cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        // destroy audio player
209cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten        (*playerObject)->Destroy(playerObject);
210cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
2119a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten        //usleep(1000000);
2129a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten        hzLeft *= 1.05946309; // twelfth root of 2
2139a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten        hzRight /= 1.05946309;
214cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    }
215cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
216cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    // destroy output mix
217cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    (*outputMixObject)->Destroy(outputMixObject);
218cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
219cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    // destroy engine
220cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    (*engineObject)->Destroy(engineObject);
221cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten
222cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten    return EXIT_SUCCESS;
223cff46f0284202c65154dd7b2f0f5542fc29f4e3fGlenn Kasten}
224