61d787d4fe21501922f1122f034237287023c67e
[WebKit-https.git] / Source / WebCore / bindings / js / JSAudioContextCustom.cpp
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 "AudioBuffer.h"
32 #include "JSArrayBuffer.h"
33 #include "JSAudioBuffer.h"
34 #include "JSAudioContext.h"
35 #include "JSOfflineAudioContext.h"
36 #include "OfflineAudioContext.h"
37 #include <runtime/Error.h>
38 #include <wtf/ArrayBuffer.h>
39
40 using namespace JSC;
41
42 namespace WebCore {
43
44 void JSAudioContext::visitChildren(JSCell* cell, SlotVisitor& visitor)
45 {
46     JSAudioContext* thisObject = jsCast<JSAudioContext*>(cell);
47     ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);
48     COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
49     ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
50     Base::visitChildren(thisObject, visitor);
51     thisObject->m_impl->visitJSEventListeners(visitor);
52 }
53
54 EncodedJSValue JSC_HOST_CALL JSAudioContextConstructor::constructJSAudioContext(ExecState* exec)
55 {
56     JSAudioContextConstructor* jsConstructor = jsCast<JSAudioContextConstructor*>(exec->callee());
57     if (!jsConstructor)
58         return throwVMError(exec, createReferenceError(exec, "AudioContext constructor callee is unavailable"));
59
60     ScriptExecutionContext* scriptExecutionContext = jsConstructor->scriptExecutionContext();
61     if (!scriptExecutionContext)
62         return throwVMError(exec, createReferenceError(exec, "AudioContext constructor script execution context is unavailable"));
63         
64     if (!scriptExecutionContext->isDocument())
65         return throwVMError(exec, createReferenceError(exec, "AudioContext constructor called in a script execution context which is not a document"));
66
67     Document* document = static_cast<Document*>(scriptExecutionContext);
68
69     RefPtr<AudioContext> audioContext;
70     
71     if (!exec->argumentCount()) {
72         // Constructor for default AudioContext which talks to audio hardware.
73         ExceptionCode ec = 0;
74         audioContext = AudioContext::create(document, ec);
75         if (ec) {
76             setDOMException(exec, ec);
77             return JSValue::encode(JSValue());
78         }
79         if (!audioContext.get())
80             return throwVMError(exec, createSyntaxError(exec, "audio resources unavailable for AudioContext construction"));
81     } else {
82 #if ENABLE(LEGACY_WEB_AUDIO)
83         // Constructor for offline (render-target) AudioContext which renders into an AudioBuffer.
84         // new AudioContext(in unsigned long numberOfChannels, in unsigned long numberOfFrames, in float sampleRate);
85         document->addConsoleMessage(JSMessageSource, WarningMessageLevel,
86             "Deprecated AudioContext constructor: use OfflineAudioContext instead");
87
88         if (exec->argumentCount() < 3)
89             return throwVMError(exec, createNotEnoughArgumentsError(exec));
90
91         int32_t numberOfChannels = exec->argument(0).toInt32(exec);
92         int32_t numberOfFrames = exec->argument(1).toInt32(exec);
93         float sampleRate = exec->argument(2).toFloat(exec);
94         
95         if (numberOfChannels <= 0 || numberOfChannels > 10)
96             return throwVMError(exec, createSyntaxError(exec, "Invalid number of channels"));
97
98         if (numberOfFrames <= 0)
99             return throwVMError(exec, createSyntaxError(exec, "Invalid number of frames"));
100
101         if (sampleRate <= 0)
102             return throwVMError(exec, createSyntaxError(exec, "Invalid sample rate"));
103
104
105         ExceptionCode ec = 0;
106         audioContext = OfflineAudioContext::create(document, numberOfChannels, numberOfFrames, sampleRate, ec);
107         if (ec) {
108             setDOMException(exec, ec);
109             return throwVMError(exec, createSyntaxError(exec, "Error creating OfflineAudioContext"));
110         }
111 #else
112         return throwVMError(exec, createSyntaxError(exec, "Illegal AudioContext constructor"));
113 #endif
114     }
115
116     if (!audioContext.get())
117         return throwVMError(exec, createReferenceError(exec, "Error creating AudioContext"));
118
119     return JSValue::encode(CREATE_DOM_WRAPPER(exec, jsConstructor->globalObject(), AudioContext, audioContext.get()));
120 }
121
122 } // namespace WebCore
123
124 #endif // ENABLE(WEB_AUDIO)