| // Copyright 2008, The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| // |
| #define LOG_NDEBUG 0 |
| #define LOG_TAG "shared_mem_test" |
| |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <cutils/properties.h> |
| #include <media/AudioSystem.h> |
| #include <media/AudioTrack.h> |
| #include <math.h> |
| |
| #include "shared_mem_test.h" |
| #include <binder/MemoryDealer.h> |
| #include <binder/MemoryHeapBase.h> |
| #include <binder/MemoryBase.h> |
| #include <binder/ProcessState.h> |
| |
| |
| #include <utils/Log.h> |
| |
| #include <fcntl.h> |
| |
| namespace android { |
| |
| /************************************************************ |
| * |
| * Constructor |
| * |
| ************************************************************/ |
| AudioTrackTest::AudioTrackTest(void) { |
| |
| InitSine(); // init sine table |
| |
| } |
| |
| |
| /************************************************************ |
| * |
| * |
| ************************************************************/ |
| void AudioTrackTest::Execute(void) { |
| if (Test01() == 0) { |
| ALOGD("01 passed\n"); |
| } else { |
| ALOGD("01 failed\n"); |
| } |
| } |
| |
| /************************************************************ |
| * |
| * Shared memory test |
| * |
| ************************************************************/ |
| #define BUF_SZ 44100 |
| |
| int AudioTrackTest::Test01() { |
| |
| sp<MemoryDealer> heap; |
| sp<IMemory> iMem; |
| uint8_t* p; |
| |
| short smpBuf[BUF_SZ]; |
| long rate = 44100; |
| unsigned long phi; |
| unsigned long dPhi; |
| long amplitude; |
| long freq = 1237; |
| float f0; |
| |
| f0 = pow(2., 32.) * freq / (float)rate; |
| dPhi = (unsigned long)f0; |
| amplitude = 1000; |
| phi = 0; |
| Generate(smpBuf, BUF_SZ, amplitude, phi, dPhi); // fill buffer |
| |
| for (int i = 0; i < 1024; i++) { |
| heap = new MemoryDealer(1024*1024, "AudioTrack Heap Base"); |
| |
| iMem = heap->allocate(BUF_SZ*sizeof(short)); |
| |
| p = static_cast<uint8_t*>(iMem->pointer()); |
| memcpy(p, smpBuf, BUF_SZ*sizeof(short)); |
| |
| sp<AudioTrack> track = new AudioTrack(AUDIO_STREAM_MUSIC,// stream type |
| rate, |
| AUDIO_FORMAT_PCM_16_BIT,// word length, PCM |
| AUDIO_CHANNEL_OUT_MONO, |
| iMem); |
| |
| status_t status = track->initCheck(); |
| if(status != NO_ERROR) { |
| track.clear(); |
| ALOGD("Failed for initCheck()"); |
| return -1; |
| } |
| |
| // start play |
| ALOGD("start"); |
| track->start(); |
| |
| usleep(20000); |
| |
| ALOGD("stop"); |
| track->stop(); |
| iMem.clear(); |
| heap.clear(); |
| usleep(20000); |
| } |
| |
| return 0; |
| |
| } |
| |
| /************************************************************ |
| * |
| * Generate a mono buffer |
| * Error is less than 3lsb |
| * |
| ************************************************************/ |
| void AudioTrackTest::Generate(short *buffer, long bufferSz, long amplitude, unsigned long &phi, long dPhi) |
| { |
| // fill buffer |
| for(int i0=0; i0<bufferSz; i0++) { |
| buffer[i0] = ComputeSine( amplitude, phi); |
| phi += dPhi; |
| } |
| } |
| |
| /************************************************************ |
| * |
| * Generate a sine |
| * Error is less than 3lsb |
| * |
| ************************************************************/ |
| short AudioTrackTest::ComputeSine(long amplitude, long phi) |
| { |
| long pi13 = 25736; // 2^13*pi |
| long sample; |
| long l0, l1; |
| |
| sample = (amplitude*sin1024[(phi>>22) & 0x3ff]) >> 15; |
| // correct with interpolation |
| l0 = (phi>>12) & 0x3ff; // 2^20 * x / (2*pi) |
| l1 = (amplitude*sin1024[((phi>>22) + 256) & 0x3ff]) >> 15; // 2^15*cosine |
| l0 = (l0 * l1) >> 10; |
| l0 = (l0 * pi13) >> 22; |
| sample = sample + l0; |
| |
| return (short)sample; |
| } |
| |
| |
| /************************************************************ |
| * |
| * init sine table |
| * |
| ************************************************************/ |
| void AudioTrackTest::InitSine(void) { |
| double phi = 0; |
| double dPhi = 2 * M_PI / SIN_SZ; |
| for(int i0 = 0; i0<SIN_SZ; i0++) { |
| long d0; |
| |
| d0 = 32768. * sin(phi); |
| phi += dPhi; |
| if(d0 >= 32767) d0 = 32767; |
| if(d0 <= -32768) d0 = -32768; |
| sin1024[i0] = (short)d0; |
| } |
| } |
| |
| /************************************************************ |
| * |
| * main in name space |
| * |
| ************************************************************/ |
| int main() { |
| ProcessState::self()->startThreadPool(); |
| AudioTrackTest *test; |
| |
| test = new AudioTrackTest(); |
| test->Execute(); |
| delete test; |
| |
| return 0; |
| } |
| |
| } |
| |
| /************************************************************ |
| * |
| * global main |
| * |
| ************************************************************/ |
| int main() { |
| |
| return android::main(); |
| } |