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 int mChannelCount; 40 }; 41 42 static ANPSampleFormat toANPFormat(audio_format_t fm) { 43 switch (fm) { 44 case AUDIO_FORMAT_PCM_16_BIT: 45 return kPCM16Bit_ANPSampleFormat; 46 case AUDIO_FORMAT_PCM_8_BIT: 47 return kPCM8Bit_ANPSampleFormat; 48 default: 49 return kUnknown_ANPSamleFormat; 50 } 51 } 52 53 static audio_format_t fromANPFormat(ANPSampleFormat fm) { 54 switch (fm) { 55 case kPCM16Bit_ANPSampleFormat: 56 return AUDIO_FORMAT_PCM_16_BIT; 57 case kPCM8Bit_ANPSampleFormat: 58 return AUDIO_FORMAT_PCM_8_BIT; 59 default: 60 return AUDIO_FORMAT_INVALID; 61 } 62 } 63 64 static void callbackProc(int event, void* user, void* info) { 65 ANPAudioTrack* track = reinterpret_cast<ANPAudioTrack*>(user); 66 67 switch (event) { 68 case android::AudioTrack::EVENT_MORE_DATA: { 69 ANPAudioBuffer dst; 70 android::AudioTrack::Buffer* src; 71 72 src = reinterpret_cast<android::AudioTrack::Buffer*>(info); 73 dst.bufferData = src->raw; 74 dst.channelCount = track->mChannelCount; 75 dst.format = toANPFormat(AUDIO_FORMAT_PCM_16_BIT); 76 dst.size = src->size; 77 track->mProc(kMoreData_ANPAudioEvent, track->mUser, &dst); 78 // return the updated size field 79 src->size = dst.size; 80 break; 81 } 82 case android::AudioTrack::EVENT_UNDERRUN: 83 track->mProc(kUnderRun_ANPAudioEvent, track->mUser, NULL); 84 break; 85 default: 86 SkDebugf("------ unknown audio event for plugin %d\n", event); 87 break; 88 } 89 } 90 91 static ANPAudioTrack* ANPCreateTrack(uint32_t sampleRate, 92 ANPSampleFormat format, 93 int channelCount, 94 ANPAudioCallbackProc proc, 95 void* user) { 96 97 ANPAudioTrack* track = new ANPAudioTrack; 98 99 track->mUser = user; 100 track->mProc = proc; 101 track->mTrack = new android::AudioTrack(AUDIO_STREAM_MUSIC, 102 sampleRate, 103 fromANPFormat(format), 104 audio_channel_out_mask_from_count(channelCount), 105 0, // frameCount 106 (audio_output_flags_t) 0, // AUDIO_OUTPUT_FLAG_NONE, 107 callbackProc, 108 track, 109 0); 110 track->mChannelCount = channelCount; 111 112 if (track->mTrack->initCheck() != 0) { // failure 113 delete track->mTrack; 114 delete track; 115 track = NULL; 116 } 117 return track; 118 } 119 120 static void ANPDeleteTrack(ANPAudioTrack* track) { 121 if (track) { 122 delete track->mTrack; 123 delete track; 124 } 125 } 126 127 static void ANPTrackStart(ANPAudioTrack* track) { 128 track->mTrack->start(); 129 } 130 131 static void ANPTrackPause(ANPAudioTrack* track) { 132 track->mTrack->pause(); 133 } 134 135 static void ANPTrackStop(ANPAudioTrack* track) { 136 track->mTrack->stop(); 137 } 138 139 static bool ANPTrackIsStopped(ANPAudioTrack* track) { 140 return track->mTrack->stopped(); 141 } 142 143 static uint32_t ANPTrackLatency(ANPAudioTrack* track) { 144 return track->mTrack->latency(); 145 } 146 147 /////////////////////////////////////////////////////////////////////////////// 148 149 void ANPAudioTrackInterfaceV0_Init(ANPInterface* value) { 150 ANPAudioTrackInterfaceV0* si = reinterpret_cast<ANPAudioTrackInterfaceV0*>(value); 151 si->newTrack = ANPCreateTrack; 152 si->deleteTrack = ANPDeleteTrack; 153 si->start = ANPTrackStart; 154 si->pause = ANPTrackPause; 155 si->stop = ANPTrackStop; 156 si->isStopped = ANPTrackIsStopped; 157 } 158 159 void ANPAudioTrackInterfaceV1_Init(ANPInterface* value) { 160 // initialize the functions from the previous interface 161 ANPAudioTrackInterfaceV0_Init(value); 162 // add any new functions or override existing functions 163 ANPAudioTrackInterfaceV1* si = reinterpret_cast<ANPAudioTrackInterfaceV1*>(value); 164 si->trackLatency = ANPTrackLatency; 165 } 166