| /** |
| * Copyright (C) 2020 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. |
| */ |
| #include <media/AudioSystem.h> |
| #include <media/AudioTrack.h> |
| #include <binder/MemoryDealer.h> |
| #include <binder/ProcessState.h> |
| #include <math.h> |
| #include "poc.h" |
| |
| namespace android { |
| |
| AudioTrackTest::AudioTrackTest(void) { |
| InitSine(); |
| } |
| |
| #define BUF_SZ 999999 |
| #define TIMEOUT_SEC 3 * 60 |
| |
| int AudioTrackTest::Test01() { |
| sp < MemoryDealer > heap; |
| sp < IMemory > iMem; |
| audio_track_cblk_t* p; |
| |
| unsigned long smpBuf[BUF_SZ]; |
| unsigned long rate = 48000; |
| unsigned long phi; |
| unsigned long dPhi; |
| unsigned long amplitude; |
| unsigned long freq = 1237; |
| unsigned f0; |
| |
| f0 = pow(2., 32.) * freq / rate; |
| dPhi = (unsigned long) f0; |
| amplitude = 1000; |
| phi = 0; |
| Generate(smpBuf, BUF_SZ, amplitude, phi, dPhi); |
| |
| heap = new MemoryDealer(7999992, "AudioTrack Heap Base"); |
| iMem = heap->allocate(BUF_SZ * sizeof(unsigned long)); |
| |
| p = static_cast<audio_track_cblk_t*>(iMem->pointer()); |
| memcpy(p, smpBuf, BUF_SZ * sizeof(unsigned long)); |
| |
| sp < AudioTrack > track = new AudioTrack(AUDIO_STREAM_MUSIC, |
| rate, AUDIO_FORMAT_PCM_16_BIT, |
| AUDIO_CHANNEL_OUT_STEREO, iMem); |
| |
| status_t status = track->initCheck(); |
| if (status != NO_ERROR) { |
| track.clear(); |
| return EXIT_SUCCESS; |
| } |
| track->start(); |
| sleep(TIMEOUT_SEC); |
| track->stop(); |
| iMem.clear(); |
| heap.clear(); |
| return EXIT_SUCCESS; |
| } |
| |
| void AudioTrackTest::Generate(unsigned long *buffer, unsigned long bufferSz, |
| unsigned long amplitude, unsigned long &phi, |
| unsigned long dPhi) { |
| for (unsigned long i0 = 0; i0 < bufferSz; i0++) { |
| buffer[i0] = ComputeSine(amplitude, phi); |
| phi += dPhi; |
| } |
| } |
| |
| unsigned long AudioTrackTest::ComputeSine(unsigned long amplitude, |
| unsigned long phi) { |
| unsigned long pi13 = 25736; |
| unsigned long sample; |
| unsigned long l0, l1; |
| |
| sample = (amplitude * sin1024[(phi >> 22) & 0x3ff]) >> 15; |
| l0 = (phi >> 12) & 0x3ff; |
| l1 = (amplitude * sin1024[((phi >> 22) + 256) & 0x3ff]) >> 15; |
| l0 = (l0 * l1) >> 10; |
| l0 = (l0 * pi13) >> 22; |
| sample = sample + l0; |
| |
| return (unsigned long) sample; |
| } |
| |
| void AudioTrackTest::InitSine(void) { |
| unsigned phi = 0; |
| unsigned dPhi = 2 * M_PI / SIN_SZ; |
| for (unsigned 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] = (long) d0; |
| } |
| } |
| } |
| |
| using namespace android; |
| int main() { |
| ProcessState::self()->startThreadPool(); |
| AudioTrackTest *test; |
| |
| test = new AudioTrackTest(); |
| test->Test01(); |
| delete test; |
| |
| return EXIT_SUCCESS; |
| } |