• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
38 using namespace JSC;
39 
40 namespace WebCore {
41 
constructJSAudioContext(ExecState * exec)42 EncodedJSValue 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 
createBuffer(ExecState * exec)81 JSValue 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