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 35struct ANPAudioTrack { 36 void* mUser; 37 ANPAudioCallbackProc mProc; 38 android::AudioTrack* mTrack; 39}; 40 41static 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 52static 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 63static 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 90static 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 audio_channel_out_mask_from_count(channelCount), 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 118static void ANPDeleteTrack(ANPAudioTrack* track) { 119 if (track) { 120 delete track->mTrack; 121 delete track; 122 } 123} 124 125static void ANPTrackStart(ANPAudioTrack* track) { 126 track->mTrack->start(); 127} 128 129static void ANPTrackPause(ANPAudioTrack* track) { 130 track->mTrack->pause(); 131} 132 133static void ANPTrackStop(ANPAudioTrack* track) { 134 track->mTrack->stop(); 135} 136 137static bool ANPTrackIsStopped(ANPAudioTrack* track) { 138 return track->mTrack->stopped(); 139} 140 141static uint32_t ANPTrackLatency(ANPAudioTrack* track) { 142 return track->mTrack->latency(); 143} 144 145/////////////////////////////////////////////////////////////////////////////// 146 147void 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 157void 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