Diff
Modified: trunk/Source/Platform/ChangeLog (144719 => 144720)
--- trunk/Source/Platform/ChangeLog 2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/Platform/ChangeLog 2013-03-05 06:04:26 UTC (rev 144720)
@@ -1,3 +1,13 @@
+2013-03-04 Chris Rogers <[email protected]>
+
+ Add audio hardware support for multi-channel by implementing AudioDestinationNode.maxChannelCount
+ https://bugs.webkit.org/show_bug.cgi?id=111385
+
+ Reviewed by James Robinson.
+
+ * chromium/public/Platform.h:
+ (WebKit::Platform::audioHardwareOutputChannels):
+
2013-02-26 Kentaro Hara <[email protected]>
[chromium] Implement TRACE_EVENT macros for sampling profiling
Modified: trunk/Source/Platform/chromium/public/Platform.h (144719 => 144720)
--- trunk/Source/Platform/chromium/public/Platform.h 2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/Platform/chromium/public/Platform.h 2013-03-05 06:04:26 UTC (rev 144720)
@@ -120,6 +120,7 @@
virtual double audioHardwareSampleRate() { return 0; }
virtual size_t audioHardwareBufferSize() { return 0; }
+ virtual unsigned audioHardwareOutputChannels() { return 0; }
// Creates a device for audio I/O.
// Pass in (numberOfInputChannels > 0) if live/local audio input is desired.
Modified: trunk/Source/WebCore/ChangeLog (144719 => 144720)
--- trunk/Source/WebCore/ChangeLog 2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/ChangeLog 2013-03-05 06:04:26 UTC (rev 144720)
@@ -1,3 +1,49 @@
+2013-03-04 Chris Rogers <[email protected]>
+
+ Add audio hardware support for multi-channel output by implementing AudioDestinationNode.maxChannelCount
+ https://bugs.webkit.org/show_bug.cgi?id=111385
+
+ Reviewed by James Robinson.
+
+ See specification details for .maxChannelCount:
+ https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AudioDestinationNode
+
+ * Modules/webaudio/AudioDestinationNode.h:
+ (WebCore::AudioDestinationNode::maxChannelCount):
+ * Modules/webaudio/AudioDestinationNode.idl:
+ * Modules/webaudio/AudioNode.h:
+ Implement .maxChannelCount attribute.
+
+ (AudioNode):
+ * Modules/webaudio/DefaultAudioDestinationNode.h:
+ * Modules/webaudio/DefaultAudioDestinationNode.cpp:
+ (WebCore::DefaultAudioDestinationNode::initialize):
+ (WebCore::DefaultAudioDestinationNode::createDestination):
+ (WebCore::DefaultAudioDestinationNode::enableInput):
+ Call to createDestination() now takes no argument.
+ Instead we maintain a member variable for the input device ID.
+ (WebCore::DefaultAudioDestinationNode::maxChannelCount):
+ (WebCore::DefaultAudioDestinationNode::setChannelCount):
+ Check port-specific hardware support for maxChannelCount(),
+ and allow setting the channel count based on what the hardware
+ supports.
+
+ * platform/audio/AudioDestination.h:
+ (AudioDestination):
+ * platform/audio/chromium/AudioDestinationChromium.cpp:
+ (WebCore::AudioDestination::maxChannelCount):
+ (WebCore::AudioDestinationChromium::render):
+ Call into chromium WebKit API: audioHardwareOutputChannels().
+
+ * platform/audio/gstreamer/AudioDestinationGStreamer.cpp:
+ (WebCore::AudioDestination::maxChannelCount):
+ Add basic implementation for maxChannelCount() only supporting stereo output.
+
+ * platform/audio/mac/AudioDestinationMac.cpp:
+ (WebCore::AudioDestination::maxChannelCount):
+ Add basic implementation for maxChannelCount() only supporting stereo output.
+ Later, the mac port can support more than this with some small improvements to AudioDestinationMac.
+
2013-03-04 Adam Barth <[email protected]>
Background HTML parser can rewind the tokenizer after end-of-file
Modified: trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.h (144719 => 144720)
--- trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.h 2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.h 2013-03-05 06:04:26 UTC (rev 144720)
@@ -52,7 +52,7 @@
size_t currentSampleFrame() const { return m_currentSampleFrame; }
double currentTime() const { return currentSampleFrame() / static_cast<double>(sampleRate()); }
- virtual unsigned numberOfChannels() const { return 2; } // FIXME: update when multi-channel (more than stereo) is supported
+ virtual unsigned long maxChannelCount() const { return 0; }
// Enable local/live input for the specified device.
virtual void enableInput(const String& inputDeviceId) = 0;
Modified: trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.idl (144719 => 144720)
--- trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.idl 2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/Modules/webaudio/AudioDestinationNode.idl 2013-03-05 06:04:26 UTC (rev 144720)
@@ -27,5 +27,5 @@
JSGenerateToJSObject,
V8SkipVTableValidation
] interface AudioDestinationNode : AudioNode {
- readonly attribute long numberOfChannels;
+ readonly attribute unsigned long maxChannelCount;
};
Modified: trunk/Source/WebCore/Modules/webaudio/AudioNode.h (144719 => 144720)
--- trunk/Source/WebCore/Modules/webaudio/AudioNode.h 2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/Modules/webaudio/AudioNode.h 2013-03-05 06:04:26 UTC (rev 144720)
@@ -169,7 +169,7 @@
void reportMemoryUsage(MemoryObjectInfo*) const;
unsigned long channelCount();
- void setChannelCount(unsigned long, ExceptionCode&);
+ virtual void setChannelCount(unsigned long, ExceptionCode&);
String channelCountMode();
void setChannelCountMode(const String&, ExceptionCode&);
Modified: trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.cpp (144719 => 144720)
--- trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.cpp 2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.cpp 2013-03-05 06:04:26 UTC (rev 144720)
@@ -28,6 +28,7 @@
#include "DefaultAudioDestinationNode.h"
+#include "ExceptionCode.h"
#include "Logging.h"
#include <wtf/MainThread.h>
@@ -56,7 +57,7 @@
if (isInitialized())
return;
- createDestination(String());
+ createDestination();
AudioNode::initialize();
}
@@ -72,12 +73,12 @@
AudioNode::uninitialize();
}
-void DefaultAudioDestinationNode::createDestination(const String& inputDeviceId)
+void DefaultAudioDestinationNode::createDestination()
{
float hardwareSampleRate = AudioDestination::hardwareSampleRate();
LOG(WebAudio, ">>>> hardwareSampleRate = %f\n", hardwareSampleRate);
- m_destination = AudioDestination::create(*this, inputDeviceId, m_numberOfInputChannels, numberOfChannels(), hardwareSampleRate);
+ m_destination = AudioDestination::create(*this, m_inputDeviceId, m_numberOfInputChannels, channelCount(), hardwareSampleRate);
}
void DefaultAudioDestinationNode::enableInput(const String& inputDeviceId)
@@ -85,11 +86,12 @@
ASSERT(isMainThread());
if (m_numberOfInputChannels != EnabledInputChannels) {
m_numberOfInputChannels = EnabledInputChannels;
+ m_inputDeviceId = inputDeviceId;
if (isInitialized()) {
// Re-create destination.
m_destination->stop();
- createDestination(inputDeviceId);
+ createDestination();
m_destination->start();
}
}
@@ -102,6 +104,35 @@
m_destination->start();
}
+unsigned long DefaultAudioDestinationNode::maxChannelCount() const
+{
+ return AudioDestination::maxChannelCount();
+}
+
+void DefaultAudioDestinationNode::setChannelCount(unsigned long channelCount, ExceptionCode& ec)
+{
+ // The channelCount for the input to this node controls the actual number of channels we
+ // send to the audio hardware. It can only be set depending on the maximum number of
+ // channels supported by the hardware.
+
+ ASSERT(isMainThread());
+
+ if (!maxChannelCount() || channelCount > maxChannelCount()) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+
+ unsigned long oldChannelCount = this->channelCount();
+ AudioNode::setChannelCount(channelCount, ec);
+
+ if (!ec && this->channelCount() != oldChannelCount && isInitialized()) {
+ // Re-create destination.
+ m_destination->stop();
+ createDestination();
+ m_destination->start();
+ }
+}
+
} // namespace WebCore
#endif // ENABLE(WEB_AUDIO)
Modified: trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.h (144719 => 144720)
--- trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.h 2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/Modules/webaudio/DefaultAudioDestinationNode.h 2013-03-05 06:04:26 UTC (rev 144720)
@@ -45,16 +45,19 @@
// AudioNode
virtual void initialize() OVERRIDE;
virtual void uninitialize() OVERRIDE;
+ virtual void setChannelCount(unsigned long, ExceptionCode&) OVERRIDE;
// AudioDestinationNode
virtual void enableInput(const String& inputDeviceId) OVERRIDE;
virtual void startRendering() OVERRIDE;
+ virtual unsigned long maxChannelCount() const OVERRIDE;
private:
explicit DefaultAudioDestinationNode(AudioContext*);
- void createDestination(const String& inputDeviceId);
+ void createDestination();
OwnPtr<AudioDestination> m_destination;
+ String m_inputDeviceId;
unsigned m_numberOfInputChannels;
};
Modified: trunk/Source/WebCore/platform/audio/AudioDestination.h (144719 => 144720)
--- trunk/Source/WebCore/platform/audio/AudioDestination.h 2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/platform/audio/AudioDestination.h 2013-03-05 06:04:26 UTC (rev 144720)
@@ -56,6 +56,14 @@
// Sample-rate conversion may happen in AudioDestination to the hardware sample-rate
virtual float sampleRate() const = 0;
static float hardwareSampleRate();
+
+ // maxChannelCount() returns the total number of output channels of the audio hardware.
+ // A value of 0 indicates that the number of channels cannot be configured and
+ // that only stereo (2-channel) destinations can be created.
+ // The numberOfOutputChannels parameter of AudioDestination::create() is allowed to
+ // be a value: 1 <= numberOfOutputChannels <= maxChannelCount(),
+ // or if maxChannelCount() equals 0, then numberOfOutputChannels must be 2.
+ static unsigned long maxChannelCount();
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/audio/chromium/AudioDestinationChromium.cpp (144719 => 144720)
--- trunk/Source/WebCore/platform/audio/chromium/AudioDestinationChromium.cpp 2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/platform/audio/chromium/AudioDestinationChromium.cpp 2013-03-05 06:04:26 UTC (rev 144720)
@@ -114,6 +114,11 @@
return static_cast<float>(WebKit::Platform::current()->audioHardwareSampleRate());
}
+unsigned long AudioDestination::maxChannelCount()
+{
+ return static_cast<float>(WebKit::Platform::current()->audioHardwareOutputChannels());
+}
+
void AudioDestinationChromium::render(const WebKit::WebVector<float*>& sourceData, const WebKit::WebVector<float*>& audioData, size_t numberOfFrames)
{
bool isNumberOfChannelsGood = audioData.size() == m_numberOfOutputChannels;
@@ -137,8 +142,8 @@
m_inputFifo->push(&wrapperBus);
}
- m_renderBus.setChannelMemory(0, audioData[0], numberOfFrames);
- m_renderBus.setChannelMemory(1, audioData[1], numberOfFrames);
+ for (unsigned i = 0; i < m_numberOfOutputChannels; ++i)
+ m_renderBus.setChannelMemory(i, audioData[i], numberOfFrames);
m_fifo->consume(&m_renderBus, numberOfFrames);
}
Modified: trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp (144719 => 144720)
--- trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp 2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp 2013-03-05 06:04:26 UTC (rev 144720)
@@ -63,6 +63,13 @@
return 44100;
}
+unsigned long AudioDestination::maxChannelCount()
+{
+ // FIXME: query the default audio hardware device to return the actual number
+ // of channels of the device. Also see corresponding FIXME in create().
+ return 0;
+}
+
#ifndef GST_API_VERSION_1
static void onGStreamerWavparsePadAddedCallback(GstElement*, GstPad* pad, AudioDestinationGStreamer* destination)
{
Modified: trunk/Source/WebCore/platform/audio/mac/AudioDestinationMac.cpp (144719 => 144720)
--- trunk/Source/WebCore/platform/audio/mac/AudioDestinationMac.cpp 2013-03-05 05:55:06 UTC (rev 144719)
+++ trunk/Source/WebCore/platform/audio/mac/AudioDestinationMac.cpp 2013-03-05 06:04:26 UTC (rev 144720)
@@ -82,6 +82,15 @@
return narrowPrecisionToFloat(nominalSampleRate);
}
+unsigned long AudioDestination::maxChannelCount()
+{
+ // FIXME: query the default audio hardware device to return the actual number
+ // of channels of the device. Also see corresponding FIXME in create().
+ // There is a small amount of code which assumes stereo in AudioDestinationMac which
+ // can be upgraded.
+ return 0;
+}
+
AudioDestinationMac::AudioDestinationMac(AudioIOCallback& callback, float sampleRate)
: m_outputUnit(0)
, m_callback(callback)