1 /* 2 * Copyright 2008, The Android Open Source Project 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 // must include config.h first for webkit to fiddle with new/delete 27 #include "config.h" 28 #include "android_npapi.h" 29 30 #include "SkTypes.h" 31 #include "media/AudioTrack.h" 32 33 #include <system/audio.h> 34 35 struct ANPAudioTrack { 36 void* mUser; 37 ANPAudioCallbackProc mProc; 38 android::AudioTrack* mTrack; 39 }; 40 41 static ANPSampleFormat toANPFormat(audio_format_t fm) { 42 switch (fm) { 43 case AUDIO_FORMAT_PCM_16_BIT: 44 return kPCM16Bit_ANPSampleFormat; 45 case AUDIO_FORMAT_PCM_8_BIT: 46 return kPCM8Bit_ANPSampleFormat; 47 default: 48 return kUnknown_ANPSamleFormat; 49 } 50 } 51 52 static audio_format_t fromANPFormat(ANPSampleFormat fm) { 53 switch (fm) { 54 case kPCM16Bit_ANPSampleFormat: 55 return AUDIO_FORMAT_PCM_16_BIT; 56 case kPCM8Bit_ANPSampleFormat: 57 return AUDIO_FORMAT_PCM_8_BIT; 58 default: 59 return AUDIO_FORMAT_INVALID; 60 } 61 } 62 63 static void callbackProc(int event, void* user, void* info) { 64 ANPAudioTrack* track = reinterpret_cast<ANPAudioTrack*>(user); 65 66 switch (event) { 67 case android::AudioTrack::EVENT_MORE_DATA: { 68 ANPAudioBuffer dst; 69 android::AudioTrack::Buffer* src; 70 71 src = reinterpret_cast<android::AudioTrack::Buffer*>(info); 72 dst.bufferData = src->raw; 73 dst.channelCount = src->channelCount; 74 dst.format = toANPFormat((audio_format_t) src->format); 75 dst.size = src->size; 76 track->mProc(kMoreData_ANPAudioEvent, track->mUser, &dst); 77 // return the updated size field 78 src->size = dst.size; 79 break; 80 } 81 case android::AudioTrack::EVENT_UNDERRUN: 82 track->mProc(kUnderRun_ANPAudioEvent, track->mUser, NULL); 83 break; 84 default: 85 SkDebugf("------ unknown audio event for plugin %d\n", event); 86 break; 87 } 88 } 89 90 static ANPAudioTrack* ANPCreateTrack(uint32_t sampleRate, 91 ANPSampleFormat format, 92 int channelCount, 93 ANPAudioCallbackProc proc, 94 void* user) { 95 96 ANPAudioTrack* track = new ANPAudioTrack; 97 98 track->mUser = user; 99 track->mProc = proc; 100 track->mTrack = new android::AudioTrack(AUDIO_STREAM_MUSIC, 101 sampleRate, 102 fromANPFormat(format), 103 (channelCount > 1) ? AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO, 104 0, // frameCount 105 (audio_output_flags_t) 0, // AUDIO_OUTPUT_FLAG_NONE, 106 callbackProc, 107 track, 108 0); 109 110 if (track->mTrack->initCheck() != 0) { // failure 111 delete track->mTrack; 112 delete track; 113 track = NULL; 114 } 115 return track; 116 } 117 118 static void ANPDeleteTrack(ANPAudioTrack* track) { 119 if (track) { 120 delete track->mTrack; 121 delete track; 122 } 123 } 124 125 static void ANPTrackStart(ANPAudioTrack* track) { 126 track->mTrack->start(); 127 } 128 129 static void ANPTrackPause(ANPAudioTrack* track) { 130 track->mTrack->pause(); 131 } 132 133 static void ANPTrackStop(ANPAudioTrack* track) { 134 track->mTrack->stop(); 135 } 136 137 static bool ANPTrackIsStopped(ANPAudioTrack* track) { 138 return track->mTrack->stopped(); 139 } 140 141 static uint32_t ANPTrackLatency(ANPAudioTrack* track) { 142 return track->mTrack->latency(); 143 } 144 145 /////////////////////////////////////////////////////////////////////////////// 146 147 void ANPAudioTrackInterfaceV0_Init(ANPInterface* value) { 148 ANPAudioTrackInterfaceV0* si = reinterpret_cast<ANPAudioTrackInterfaceV0*>(value); 149 si->newTrack = ANPCreateTrack; 150 si->deleteTrack = ANPDeleteTrack; 151 si->start = ANPTrackStart; 152 si->pause = ANPTrackPause; 153 si->stop = ANPTrackStop; 154 si->isStopped = ANPTrackIsStopped; 155 } 156 157 void ANPAudioTrackInterfaceV1_Init(ANPInterface* value) { 158 // initialize the functions from the previous interface 159 ANPAudioTrackInterfaceV0_Init(value); 160 // add any new functions or override existing functions 161 ANPAudioTrackInterfaceV1* si = reinterpret_cast<ANPAudioTrackInterfaceV1*>(value); 162 si->trackLatency = ANPTrackLatency; 163 } 164