18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright 2008, The Android Open Source Project 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * * Redistributions of source code must retain the above copyright 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * * Redistributions in binary form must reproduce the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 163298a7d84b96ade73c6b170671711a8f2792ae59Steve Block * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// must include config.h first for webkit to fiddle with new/delete 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "android_npapi.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 30a47ab5294213cca2741f453b450b02666e08cac8Patrick Scott#include "SkTypes.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "media/AudioTrack.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3373721b27032fa99cefeffd85bc62787f8895636aDima Zavin#include <system/audio.h> 34ae523aafcb7b5f04cd5ad61ab37e546ca7ca6df2Dima Zavin 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstruct ANPAudioTrack { 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project void* mUser; 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ANPAudioCallbackProc mProc; 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project android::AudioTrack* mTrack; 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}; 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 41aec70f340dd665e5c3bf3ef7aed3bae2fe55996dGlenn Kastenstatic ANPSampleFormat toANPFormat(audio_format_t fm) { 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project switch (fm) { 43ae523aafcb7b5f04cd5ad61ab37e546ca7ca6df2Dima Zavin case AUDIO_FORMAT_PCM_16_BIT: 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return kPCM16Bit_ANPSampleFormat; 45ae523aafcb7b5f04cd5ad61ab37e546ca7ca6df2Dima Zavin case AUDIO_FORMAT_PCM_8_BIT: 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return kPCM8Bit_ANPSampleFormat; 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project default: 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return kUnknown_ANPSamleFormat; 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 52aec70f340dd665e5c3bf3ef7aed3bae2fe55996dGlenn Kastenstatic audio_format_t fromANPFormat(ANPSampleFormat fm) { 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project switch (fm) { 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case kPCM16Bit_ANPSampleFormat: 55ae523aafcb7b5f04cd5ad61ab37e546ca7ca6df2Dima Zavin return AUDIO_FORMAT_PCM_16_BIT; 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case kPCM8Bit_ANPSampleFormat: 57ae523aafcb7b5f04cd5ad61ab37e546ca7ca6df2Dima Zavin return AUDIO_FORMAT_PCM_8_BIT; 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project default: 59ae523aafcb7b5f04cd5ad61ab37e546ca7ca6df2Dima Zavin return AUDIO_FORMAT_INVALID; 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 63131e4ececc5afb847b251dc85fff81e1cb41a94aGlenn Kastenstatic void callbackProc(int event, void* user, void* info) { 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ANPAudioTrack* track = reinterpret_cast<ANPAudioTrack*>(user); 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project switch (event) { 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case android::AudioTrack::EVENT_MORE_DATA: { 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ANPAudioBuffer dst; 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project android::AudioTrack::Buffer* src; 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project src = reinterpret_cast<android::AudioTrack::Buffer*>(info); 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project dst.bufferData = src->raw; 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project dst.channelCount = src->channelCount; 745a2206b6d2861a63585471a526dda333f68d3ebcGlenn Kasten dst.format = toANPFormat((audio_format_t) src->format); 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project dst.size = src->size; 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project track->mProc(kMoreData_ANPAudioEvent, track->mUser, &dst); 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // return the updated size field 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project src->size = dst.size; 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project case android::AudioTrack::EVENT_UNDERRUN: 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project track->mProc(kUnderRun_ANPAudioEvent, track->mUser, NULL); 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project default: 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project SkDebugf("------ unknown audio event for plugin %d\n", event); 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic ANPAudioTrack* ANPCreateTrack(uint32_t sampleRate, 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ANPSampleFormat format, 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int channelCount, 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ANPAudioCallbackProc proc, 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project void* user) { 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ANPAudioTrack* track = new ANPAudioTrack; 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project track->mUser = user; 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project track->mProc = proc; 100ae523aafcb7b5f04cd5ad61ab37e546ca7ca6df2Dima Zavin track->mTrack = new android::AudioTrack(AUDIO_STREAM_MUSIC, 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project sampleRate, 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project fromANPFormat(format), 1034700ce519e61bebe0435ca117d2ea24d78eae63fGlenn Kasten audio_channel_out_mask_from_count(channelCount), 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 0, // frameCount 105356edf790717717a9f3b88deb7b80941fb052923Eric Laurent (audio_output_flags_t) 0, // AUDIO_OUTPUT_FLAG_NONE, 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callbackProc, 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project track, 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 0); 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (track->mTrack->initCheck() != 0) { // failure 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete track->mTrack; 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete track; 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project track = NULL; 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return track; 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void ANPDeleteTrack(ANPAudioTrack* track) { 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (track) { 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete track->mTrack; 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete track; 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void ANPTrackStart(ANPAudioTrack* track) { 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project track->mTrack->start(); 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void ANPTrackPause(ANPAudioTrack* track) { 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project track->mTrack->pause(); 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void ANPTrackStop(ANPAudioTrack* track) { 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project track->mTrack->stop(); 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool ANPTrackIsStopped(ANPAudioTrack* track) { 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return track->mTrack->stopped(); 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 14149bf866973cb3b2a6c74c0eab864e9562e4cbab1Derek Sollenbergerstatic uint32_t ANPTrackLatency(ANPAudioTrack* track) { 14249bf866973cb3b2a6c74c0eab864e9562e4cbab1Derek Sollenberger return track->mTrack->latency(); 14349bf866973cb3b2a6c74c0eab864e9562e4cbab1Derek Sollenberger} 14449bf866973cb3b2a6c74c0eab864e9562e4cbab1Derek Sollenberger 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid ANPAudioTrackInterfaceV0_Init(ANPInterface* value) { 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ANPAudioTrackInterfaceV0* si = reinterpret_cast<ANPAudioTrackInterfaceV0*>(value); 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project si->newTrack = ANPCreateTrack; 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project si->deleteTrack = ANPDeleteTrack; 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project si->start = ANPTrackStart; 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project si->pause = ANPTrackPause; 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project si->stop = ANPTrackStop; 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project si->isStopped = ANPTrackIsStopped; 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 15649bf866973cb3b2a6c74c0eab864e9562e4cbab1Derek Sollenberger 15749bf866973cb3b2a6c74c0eab864e9562e4cbab1Derek Sollenbergervoid ANPAudioTrackInterfaceV1_Init(ANPInterface* value) { 15849bf866973cb3b2a6c74c0eab864e9562e4cbab1Derek Sollenberger // initialize the functions from the previous interface 15949bf866973cb3b2a6c74c0eab864e9562e4cbab1Derek Sollenberger ANPAudioTrackInterfaceV0_Init(value); 16049bf866973cb3b2a6c74c0eab864e9562e4cbab1Derek Sollenberger // add any new functions or override existing functions 16149bf866973cb3b2a6c74c0eab864e9562e4cbab1Derek Sollenberger ANPAudioTrackInterfaceV1* si = reinterpret_cast<ANPAudioTrackInterfaceV1*>(value); 16249bf866973cb3b2a6c74c0eab864e9562e4cbab1Derek Sollenberger si->trackLatency = ANPTrackLatency; 16349bf866973cb3b2a6c74c0eab864e9562e4cbab1Derek Sollenberger} 164