Home | History | Annotate | Download | only in webaudio
      1 /*
      2  * Copyright (C) 2011, Google Inc. All rights reserved.
      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  * 1.  Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2.  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 APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     23  */
     24 
     25 #include "config.h"
     26 
     27 #if ENABLE(WEB_AUDIO)
     28 
     29 #include "modules/webaudio/AsyncAudioDecoder.h"
     30 
     31 #include "modules/webaudio/AudioBuffer.h"
     32 #include "modules/webaudio/AudioBufferCallback.h"
     33 #include "platform/Task.h"
     34 #include "public/platform/Platform.h"
     35 #include "wtf/ArrayBuffer.h"
     36 #include "wtf/MainThread.h"
     37 #include "wtf/PassOwnPtr.h"
     38 
     39 namespace WebCore {
     40 
     41 AsyncAudioDecoder::AsyncAudioDecoder()
     42     : m_thread(adoptPtr(blink::Platform::current()->createThread("Audio Decoder")))
     43 {
     44 }
     45 
     46 AsyncAudioDecoder::~AsyncAudioDecoder()
     47 {
     48 }
     49 
     50 void AsyncAudioDecoder::decodeAsync(ArrayBuffer* audioData, float sampleRate, PassOwnPtr<AudioBufferCallback> successCallback, PassOwnPtr<AudioBufferCallback> errorCallback)
     51 {
     52     ASSERT(isMainThread());
     53     ASSERT(audioData);
     54     if (!audioData)
     55         return;
     56 
     57     // Add a ref to keep audioData alive until completion of decoding.
     58     RefPtr<ArrayBuffer> audioDataRef(audioData);
     59 
     60     // The leak references to successCallback and errorCallback are picked up on notifyComplete.
     61     m_thread->postTask(new Task(WTF::bind(&AsyncAudioDecoder::decode, audioDataRef.release().leakRef(), sampleRate, successCallback.leakPtr(), errorCallback.leakPtr())));
     62 }
     63 
     64 void AsyncAudioDecoder::decode(ArrayBuffer* audioData, float sampleRate, AudioBufferCallback* successCallback, AudioBufferCallback* errorCallback)
     65 {
     66     // Do the actual decoding and invoke the callback.
     67     RefPtr<AudioBuffer> audioBuffer = AudioBuffer::createFromAudioFileData(audioData->data(), audioData->byteLength(), false, sampleRate);
     68 
     69     // Decoding is finished, but we need to do the callbacks on the main thread.
     70     // The leaked reference to audioBuffer is picked up in notifyComplete.
     71     callOnMainThread(WTF::bind(&AsyncAudioDecoder::notifyComplete, audioData, successCallback, errorCallback, audioBuffer.release().leakRef()));
     72 }
     73 
     74 void AsyncAudioDecoder::notifyComplete(ArrayBuffer* audioData, AudioBufferCallback* successCallback, AudioBufferCallback* errorCallback, AudioBuffer* audioBuffer)
     75 {
     76     // Adopt references, so everything gets correctly dereffed.
     77     RefPtr<ArrayBuffer> audioDataRef = adoptRef(audioData);
     78     OwnPtr<AudioBufferCallback> successCallbackPtr = adoptPtr(successCallback);
     79     OwnPtr<AudioBufferCallback> errorCallbackPtr = adoptPtr(errorCallback);
     80     RefPtr<AudioBuffer> audioBufferRef = adoptRef(audioBuffer);
     81 
     82     if (audioBuffer && successCallback)
     83         successCallback->handleEvent(audioBuffer);
     84     else if (errorCallback)
     85         errorCallback->handleEvent(audioBuffer);
     86 }
     87 
     88 } // namespace WebCore
     89 
     90 #endif // ENABLE(WEB_AUDIO)
     91