• 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 "V8AudioContext.h"
30 
31 #include "ArrayBuffer.h"
32 #include "AudioBuffer.h"
33 #include "AudioContext.h"
34 #include "Frame.h"
35 #include "V8ArrayBuffer.h"
36 #include "V8AudioBuffer.h"
37 #include "V8Binding.h"
38 #include "V8Proxy.h"
39 
40 namespace WebCore {
41 
constructorCallback(const v8::Arguments & args)42 v8::Handle<v8::Value> V8AudioContext::constructorCallback(const v8::Arguments& args)
43 {
44     INC_STATS("DOM.AudioContext.Contructor");
45 
46     Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
47     if (!frame)
48         return throwError("AudioContext constructor associated frame is unavailable", V8Proxy::ReferenceError);
49 
50     Document* document = frame->document();
51     if (!document)
52         return throwError("AudioContext constructor associated document is unavailable", V8Proxy::ReferenceError);
53 
54     RefPtr<AudioContext> audioContext;
55 
56     if (!args.Length()) {
57         // Constructor for default AudioContext which talks to audio hardware.
58         audioContext = AudioContext::create(document);
59     } else {
60         // Constructor for offline (render-target) AudioContext which renders into an AudioBuffer.
61         // new AudioContext(in unsigned long numberOfChannels, in unsigned long numberOfFrames, in float sampleRate);
62         if (args.Length() < 3)
63             return throwError("Not enough arguments", V8Proxy::SyntaxError);
64 
65         bool ok = false;
66 
67         unsigned numberOfChannels = toInt32(args[0], ok);
68         if (!ok)
69             return throwError("Invalid number of channels", V8Proxy::SyntaxError);
70 
71         unsigned numberOfFrames = toInt32(args[1], ok);
72         if (!ok)
73             return throwError("Invalid number of frames", V8Proxy::SyntaxError);
74 
75         float sampleRate = toFloat(args[2]);
76 
77         audioContext = AudioContext::createOfflineContext(document, numberOfChannels, numberOfFrames, sampleRate);
78     }
79 
80     if (!audioContext.get())
81         return throwError("Error creating AudioContext", V8Proxy::SyntaxError);
82 
83     // Transform the holder into a wrapper object for the audio context.
84     V8DOMWrapper::setDOMWrapper(args.Holder(), &info, audioContext.get());
85     audioContext->ref();
86 
87     return args.Holder();
88 }
89 
createBufferCallback(const v8::Arguments & args)90 v8::Handle<v8::Value> V8AudioContext::createBufferCallback(const v8::Arguments& args)
91 {
92     if (args.Length() < 2)
93         return throwError("Not enough arguments", V8Proxy::SyntaxError);
94 
95     AudioContext* audioContext = toNative(args.Holder());
96     ASSERT(audioContext);
97 
98     v8::Handle<v8::Value> arg = args[0];
99 
100     // AudioBuffer createBuffer(in ArrayBuffer buffer, in boolean mixToMono);
101     if (V8ArrayBuffer::HasInstance(arg)) {
102         v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg);
103         ArrayBuffer* arrayBuffer = V8ArrayBuffer::toNative(object);
104         ASSERT(arrayBuffer);
105 
106         if (arrayBuffer) {
107             bool mixToMono = args[1]->ToBoolean()->Value();
108 
109             RefPtr<AudioBuffer> audioBuffer = audioContext->createBuffer(arrayBuffer, mixToMono);
110             if (!audioBuffer.get())
111                 return throwError("Error decoding audio file data", V8Proxy::SyntaxError);
112 
113             return toV8(audioBuffer.get());
114         }
115 
116         return v8::Undefined();
117     }
118 
119     // AudioBuffer createBuffer(in unsigned long numberOfChannels, in unsigned long numberOfFrames, in float sampleRate);
120     if (args.Length() < 3)
121         return throwError("Not enough arguments", V8Proxy::SyntaxError);
122 
123     bool ok = false;
124 
125     unsigned numberOfChannels = toInt32(args[0], ok);
126     if (!ok)
127         return throwError("Invalid number of channels", V8Proxy::SyntaxError);
128 
129     unsigned numberOfFrames = toInt32(args[1], ok);
130     if (!ok)
131         return throwError("Invalid number of frames", V8Proxy::SyntaxError);
132 
133     float sampleRate = toFloat(args[2]);
134 
135     RefPtr<AudioBuffer> audioBuffer = audioContext->createBuffer(numberOfChannels, numberOfFrames, sampleRate);
136     if (!audioBuffer.get())
137         return throwError("Error creating AudioBuffer", V8Proxy::SyntaxError);
138 
139     return toV8(audioBuffer.get());
140 }
141 
142 } // namespace WebCore
143 
144 #endif // ENABLE(WEB_AUDIO)
145