Home | History | Annotate | Download | only in plugins
      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