1/* 2 * Copyright (C) 2010, 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 "AudioContext.h" 30 31#include "ArrayBuffer.h" 32#include "AudioBuffer.h" 33#include "JSArrayBuffer.h" 34#include "JSAudioBuffer.h" 35#include "JSAudioContext.h" 36#include <runtime/Error.h> 37 38using namespace JSC; 39 40namespace WebCore { 41 42EncodedJSValue JSC_HOST_CALL JSAudioContextConstructor::constructJSAudioContext(ExecState* exec) 43{ 44 JSAudioContextConstructor* jsConstructor = static_cast<JSAudioContextConstructor*>(exec->callee()); 45 if (!jsConstructor) 46 return throwError(exec, createReferenceError(exec, "AudioContext constructor callee is unavailable")); 47 48 ScriptExecutionContext* scriptExecutionContext = jsConstructor->scriptExecutionContext(); 49 if (!scriptExecutionContext) 50 return throwError(exec, createReferenceError(exec, "AudioContext constructor script execution context is unavailable")); 51 52 if (!scriptExecutionContext->isDocument()) 53 return throwError(exec, createReferenceError(exec, "AudioContext constructor called in a script execution context which is not a document")); 54 55 Document* document = static_cast<Document*>(scriptExecutionContext); 56 57 RefPtr<AudioContext> audioContext; 58 59 if (!exec->argumentCount()) { 60 // Constructor for default AudioContext which talks to audio hardware. 61 audioContext = AudioContext::create(document); 62 } else { 63 // Constructor for offline (render-target) AudioContext which renders into an AudioBuffer. 64 // new AudioContext(in unsigned long numberOfChannels, in unsigned long numberOfFrames, in float sampleRate); 65 if (exec->argumentCount() < 3) 66 return throwError(exec, createSyntaxError(exec, "Not enough arguments")); 67 68 unsigned numberOfChannels = exec->argument(0).toInt32(exec); 69 unsigned numberOfFrames = exec->argument(1).toInt32(exec); 70 float sampleRate = exec->argument(2).toFloat(exec); 71 72 audioContext = AudioContext::createOfflineContext(document, numberOfChannels, numberOfFrames, sampleRate); 73 } 74 75 if (!audioContext.get()) 76 return throwError(exec, createReferenceError(exec, "Error creating AudioContext")); 77 78 return JSValue::encode(asObject(toJS(exec, jsConstructor->globalObject(), audioContext.get()))); 79} 80 81JSValue JSAudioContext::createBuffer(ExecState* exec) 82{ 83 if (exec->argumentCount() < 2) 84 return throwError(exec, createSyntaxError(exec, "Not enough arguments")); 85 86 AudioContext* audioContext = static_cast<AudioContext*>(impl()); 87 ASSERT(audioContext); 88 89 // AudioBuffer createBuffer(in ArrayBuffer buffer, in boolean mixToMono); 90 JSValue val = exec->argument(0); 91 if (val.inherits(&JSArrayBuffer::s_info)) { 92 ArrayBuffer* arrayBuffer = toArrayBuffer(val); 93 ASSERT(arrayBuffer); 94 if (arrayBuffer) { 95 bool mixToMono = exec->argument(1).toBoolean(exec); 96 97 RefPtr<AudioBuffer> audioBuffer = audioContext->createBuffer(arrayBuffer, mixToMono); 98 if (!audioBuffer.get()) 99 return throwError(exec, createSyntaxError(exec, "Error decoding audio file data")); 100 101 return toJS(exec, globalObject(), audioBuffer.get()); 102 } 103 104 return jsUndefined(); 105 } 106 107 // AudioBuffer createBuffer(in unsigned long numberOfChannels, in unsigned long numberOfFrames, in float sampleRate); 108 if (exec->argumentCount() < 3) 109 return throwError(exec, createSyntaxError(exec, "Not enough arguments")); 110 111 unsigned numberOfChannels = exec->argument(0).toInt32(exec); 112 unsigned numberOfFrames = exec->argument(1).toInt32(exec); 113 float sampleRate = exec->argument(2).toFloat(exec); 114 115 RefPtr<AudioBuffer> audioBuffer = audioContext->createBuffer(numberOfChannels, numberOfFrames, sampleRate); 116 if (!audioBuffer.get()) 117 return throwError(exec, createSyntaxError(exec, "Error creating AudioBuffer")); 118 119 return toJS(exec, globalObject(), audioBuffer.get()); 120} 121 122} // namespace WebCore 123 124#endif // ENABLE(WEB_AUDIO) 125