Home | History | Annotate | Download | only in custom
      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 
     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 
     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