1// Copyright 2008, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//
16#define LOG_NDEBUG 0
17#define LOG_TAG "shared_mem_test"
18
19#include <stdlib.h>
20#include <stdio.h>
21#include <cutils/properties.h>
22#include <media/AudioSystem.h>
23#include <media/AudioTrack.h>
24#include <math.h>
25
26#include "shared_mem_test.h"
27#include <binder/MemoryDealer.h>
28#include <binder/MemoryHeapBase.h>
29#include <binder/MemoryBase.h>
30#include <binder/ProcessState.h>
31
32
33#include <utils/Log.h>
34
35#include <fcntl.h>
36
37namespace android {
38
39/************************************************************
40*
41*    Constructor
42*
43************************************************************/
44AudioTrackTest::AudioTrackTest(void) {
45
46    InitSine();         // init sine table
47
48}
49
50
51/************************************************************
52*
53*
54************************************************************/
55void AudioTrackTest::Execute(void) {
56    if (Test01() == 0) {
57        ALOGD("01 passed\n");
58    } else {
59        ALOGD("01 failed\n");
60    }
61}
62
63/************************************************************
64*
65*    Shared memory test
66*
67************************************************************/
68#define BUF_SZ 44100
69
70int AudioTrackTest::Test01() {
71
72    sp<MemoryDealer> heap;
73    sp<IMemory> iMem;
74    uint8_t* p;
75
76    short smpBuf[BUF_SZ];
77    long rate = 44100;
78    unsigned long phi;
79    unsigned long dPhi;
80    long amplitude;
81    long freq = 1237;
82    float f0;
83
84    f0 = pow(2., 32.) * freq / (float)rate;
85    dPhi = (unsigned long)f0;
86    amplitude = 1000;
87    phi = 0;
88    Generate(smpBuf, BUF_SZ, amplitude, phi, dPhi);  // fill buffer
89
90    for (int i = 0; i < 1024; i++) {
91        heap = new MemoryDealer(1024*1024, "AudioTrack Heap Base");
92
93        iMem = heap->allocate(BUF_SZ*sizeof(short));
94
95        p = static_cast<uint8_t*>(iMem->pointer());
96        memcpy(p, smpBuf, BUF_SZ*sizeof(short));
97
98        sp<AudioTrack> track = new AudioTrack(AUDIO_STREAM_MUSIC,// stream type
99               rate,
100               AUDIO_FORMAT_PCM_16_BIT,// word length, PCM
101               AUDIO_CHANNEL_OUT_MONO,
102               iMem);
103
104        status_t status = track->initCheck();
105        if(status != NO_ERROR) {
106            track.clear();
107            ALOGD("Failed for initCheck()");
108            return -1;
109        }
110
111        // start play
112        ALOGD("start");
113        track->start();
114
115        usleep(20000);
116
117        ALOGD("stop");
118        track->stop();
119        iMem.clear();
120        heap.clear();
121        usleep(20000);
122    }
123
124    return 0;
125
126}
127
128/************************************************************
129*
130*    Generate a mono buffer
131*    Error is less than 3lsb
132*
133************************************************************/
134void AudioTrackTest::Generate(short *buffer, long bufferSz, long amplitude, unsigned long &phi, long dPhi)
135{
136    long pi13 = 25736;   // 2^13*pi
137    // fill buffer
138    for(int i0=0; i0<bufferSz; i0++) {
139        long sample;
140        long l0, l1;
141
142        buffer[i0] = ComputeSine( amplitude, phi);
143        phi += dPhi;
144    }
145}
146
147/************************************************************
148*
149*    Generate a sine
150*    Error is less than 3lsb
151*
152************************************************************/
153short AudioTrackTest::ComputeSine(long amplitude, long phi)
154{
155    long pi13 = 25736;   // 2^13*pi
156    long sample;
157    long l0, l1;
158
159    sample = (amplitude*sin1024[(phi>>22) & 0x3ff]) >> 15;
160    // correct with interpolation
161    l0 = (phi>>12) & 0x3ff;         // 2^20 * x / (2*pi)
162    l1 = (amplitude*sin1024[((phi>>22) + 256) & 0x3ff]) >> 15;    // 2^15*cosine
163    l0 = (l0 * l1) >> 10;
164    l0 = (l0 * pi13) >> 22;
165    sample = sample + l0;
166
167    return (short)sample;
168}
169
170
171/************************************************************
172*
173*    init sine table
174*
175************************************************************/
176void AudioTrackTest::InitSine(void) {
177    double phi = 0;
178    double dPhi = 2 * M_PI / SIN_SZ;
179    for(int i0 = 0; i0<SIN_SZ; i0++) {
180        long d0;
181
182        d0 = 32768. * sin(phi);
183        phi += dPhi;
184        if(d0 >= 32767) d0 = 32767;
185        if(d0 <= -32768) d0 = -32768;
186        sin1024[i0] = (short)d0;
187    }
188}
189
190/************************************************************
191*
192*    main in name space
193*
194************************************************************/
195int main() {
196    ProcessState::self()->startThreadPool();
197    AudioTrackTest *test;
198
199    test = new AudioTrackTest();
200    test->Execute();
201    delete test;
202
203    return 0;
204}
205
206}
207
208/************************************************************
209*
210*    global main
211*
212************************************************************/
213int main(int argc, char *argv[]) {
214
215    return android::main();
216}
217