AsyncAudioDecoder.cpp [plain text]
#include "config.h"
#if ENABLE(WEB_AUDIO)
#include "AsyncAudioDecoder.h"
#include "AudioBuffer.h"
#include "AudioBufferCallback.h"
#include <wtf/ArrayBuffer.h>
#include <wtf/MainThread.h>
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
namespace WebCore {
AsyncAudioDecoder::AsyncAudioDecoder()
{
MutexLocker lock(m_threadCreationMutex);
m_threadID = createThread(AsyncAudioDecoder::threadEntry, this, "Audio Decoder");
}
AsyncAudioDecoder::~AsyncAudioDecoder()
{
m_queue.kill();
waitForThreadCompletion(m_threadID);
m_threadID = 0;
}
void AsyncAudioDecoder::decodeAsync(ArrayBuffer* audioData, float sampleRate, PassRefPtr<AudioBufferCallback> successCallback, PassRefPtr<AudioBufferCallback> errorCallback)
{
ASSERT(isMainThread());
ASSERT(audioData);
if (!audioData)
return;
OwnPtr<DecodingTask> decodingTask = DecodingTask::create(audioData, sampleRate, successCallback, errorCallback);
m_queue.append(decodingTask.release()); }
void AsyncAudioDecoder::threadEntry(void* threadData)
{
ASSERT(threadData);
AsyncAudioDecoder* decoder = reinterpret_cast<AsyncAudioDecoder*>(threadData);
decoder->runLoop();
}
void AsyncAudioDecoder::runLoop()
{
ASSERT(!isMainThread());
{
MutexLocker lock(m_threadCreationMutex);
}
while (OwnPtr<DecodingTask> decodingTask = m_queue.waitForMessage()) {
decodingTask.leakPtr()->decode();
}
}
PassOwnPtr<AsyncAudioDecoder::DecodingTask> AsyncAudioDecoder::DecodingTask::create(ArrayBuffer* audioData, float sampleRate, PassRefPtr<AudioBufferCallback> successCallback, PassRefPtr<AudioBufferCallback> errorCallback)
{
return adoptPtr(new DecodingTask(audioData, sampleRate, successCallback, errorCallback));
}
AsyncAudioDecoder::DecodingTask::DecodingTask(ArrayBuffer* audioData, float sampleRate, PassRefPtr<AudioBufferCallback> successCallback, PassRefPtr<AudioBufferCallback> errorCallback)
: m_audioData(audioData)
, m_sampleRate(sampleRate)
, m_successCallback(successCallback)
, m_errorCallback(errorCallback)
{
}
void AsyncAudioDecoder::DecodingTask::decode()
{
ASSERT(m_audioData.get());
if (!m_audioData.get())
return;
m_audioBuffer = AudioBuffer::createFromAudioFileData(m_audioData->data(), m_audioData->byteLength(), false, sampleRate());
callOnMainThread(notifyCompleteDispatch, this);
}
void AsyncAudioDecoder::DecodingTask::notifyCompleteDispatch(void* userData)
{
AsyncAudioDecoder::DecodingTask* task = reinterpret_cast<AsyncAudioDecoder::DecodingTask*>(userData);
ASSERT(task);
if (!task)
return;
task->notifyComplete();
}
void AsyncAudioDecoder::DecodingTask::notifyComplete()
{
if (audioBuffer() && successCallback())
successCallback()->handleEvent(audioBuffer());
else if (errorCallback())
errorCallback()->handleEvent(audioBuffer());
delete this;
}
}
#endif // ENABLE(WEB_AUDIO)