Home | History | Annotate | Download | only in webaudio
      1 /*
      2  * Copyright (C) 2011, 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 "modules/webaudio/DefaultAudioDestinationNode.h"
     30 
     31 #include "bindings/v8/ExceptionState.h"
     32 #include "core/dom/ExceptionCode.h"
     33 #include "core/platform/Logging.h"
     34 #include "wtf/MainThread.h"
     35 
     36 const unsigned EnabledInputChannels = 2;
     37 
     38 namespace WebCore {
     39 
     40 DefaultAudioDestinationNode::DefaultAudioDestinationNode(AudioContext* context)
     41     : AudioDestinationNode(context, AudioDestination::hardwareSampleRate())
     42     , m_numberOfInputChannels(0)
     43 {
     44     // Node-specific default mixing rules.
     45     m_channelCount = 2;
     46     m_channelCountMode = Explicit;
     47     m_channelInterpretation = AudioBus::Speakers;
     48 }
     49 
     50 DefaultAudioDestinationNode::~DefaultAudioDestinationNode()
     51 {
     52     uninitialize();
     53 }
     54 
     55 void DefaultAudioDestinationNode::initialize()
     56 {
     57     ASSERT(isMainThread());
     58     if (isInitialized())
     59         return;
     60 
     61     createDestination();
     62     AudioNode::initialize();
     63 }
     64 
     65 void DefaultAudioDestinationNode::uninitialize()
     66 {
     67     ASSERT(isMainThread());
     68     if (!isInitialized())
     69         return;
     70 
     71     m_destination->stop();
     72     m_numberOfInputChannels = 0;
     73 
     74     AudioNode::uninitialize();
     75 }
     76 
     77 void DefaultAudioDestinationNode::createDestination()
     78 {
     79     float hardwareSampleRate = AudioDestination::hardwareSampleRate();
     80     LOG(WebAudio, ">>>> hardwareSampleRate = %f\n", hardwareSampleRate);
     81 
     82     m_destination = AudioDestination::create(*this, m_inputDeviceId, m_numberOfInputChannels, channelCount(), hardwareSampleRate);
     83 }
     84 
     85 void DefaultAudioDestinationNode::enableInput(const String& inputDeviceId)
     86 {
     87     ASSERT(isMainThread());
     88     if (m_numberOfInputChannels != EnabledInputChannels) {
     89         m_numberOfInputChannels = EnabledInputChannels;
     90         m_inputDeviceId = inputDeviceId;
     91 
     92         if (isInitialized()) {
     93             // Re-create destination.
     94             m_destination->stop();
     95             createDestination();
     96             m_destination->start();
     97         }
     98     }
     99 }
    100 
    101 void DefaultAudioDestinationNode::startRendering()
    102 {
    103     ASSERT(isInitialized());
    104     if (isInitialized())
    105         m_destination->start();
    106 }
    107 
    108 unsigned long DefaultAudioDestinationNode::maxChannelCount() const
    109 {
    110     return AudioDestination::maxChannelCount();
    111 }
    112 
    113 void DefaultAudioDestinationNode::setChannelCount(unsigned long channelCount, ExceptionState& es)
    114 {
    115     // The channelCount for the input to this node controls the actual number of channels we
    116     // send to the audio hardware. It can only be set depending on the maximum number of
    117     // channels supported by the hardware.
    118 
    119     ASSERT(isMainThread());
    120 
    121     if (!maxChannelCount() || channelCount > maxChannelCount()) {
    122         es.throwDOMException(InvalidStateError);
    123         return;
    124     }
    125 
    126     unsigned long oldChannelCount = this->channelCount();
    127     AudioNode::setChannelCount(channelCount, es);
    128 
    129     if (!es.hadException() && this->channelCount() != oldChannelCount && isInitialized()) {
    130         // Re-create destination.
    131         m_destination->stop();
    132         createDestination();
    133         m_destination->start();
    134     }
    135 }
    136 
    137 } // namespace WebCore
    138 
    139 #endif // ENABLE(WEB_AUDIO)
    140