summaryrefslogtreecommitdiffstats
path: root/src/multimedia
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@nokia.com>2010-07-15 13:08:38 (GMT)
committerThiago Macieira <thiago.macieira@nokia.com>2010-07-15 13:08:38 (GMT)
commit8cda4ebd5611a6680cd311ff7cadfcc43c6f1686 (patch)
tree9f1813234d33b577951e21eee7d81f65c1f20769 /src/multimedia
parent03c01176ebf423085e56ceabcf8335ca5027a786 (diff)
parent77edce14629b665924e89b1f22f902ceb010c964 (diff)
downloadQt-8cda4ebd5611a6680cd311ff7cadfcc43c6f1686.zip
Qt-8cda4ebd5611a6680cd311ff7cadfcc43c6f1686.tar.gz
Qt-8cda4ebd5611a6680cd311ff7cadfcc43c6f1686.tar.bz2
Merge remote branch 'origin/4.6' into qt-4.7-from-4.6
Conflicts: bin/syncqt src/3rdparty/webkit/VERSION src/3rdparty/webkit/WebCore/ChangeLog src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.h src/3rdparty/webkit/WebCore/page/FrameView.cpp src/3rdparty/webkit/WebCore/page/FrameView.h src/3rdparty/webkit/WebCore/platform/ScrollView.cpp src/3rdparty/webkit/WebCore/platform/ScrollView.h src/corelib/plugin/quuid.cpp src/gui/dialogs/qfontdialog.cpp src/multimedia/audio/qaudiodevicefactory.cpp src/opengl/qgl.cpp src/openvg/qpaintengine_vg.cpp tests/auto/qxmlquery/tst_qxmlquery.cpp
Diffstat (limited to 'src/multimedia')
-rw-r--r--src/multimedia/audio/qaudiodevicefactory.cpp22
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp46
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo_alsa_p.h5
-rw-r--r--src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp5
-rw-r--r--src/multimedia/audio/qaudioinput_alsa_p.cpp54
-rw-r--r--src/multimedia/audio/qaudioinput_alsa_p.h1
-rw-r--r--src/multimedia/audio/qaudioinput_win32_p.cpp2
-rw-r--r--src/multimedia/audio/qaudiooutput_win32_p.cpp101
8 files changed, 196 insertions, 40 deletions
diff --git a/src/multimedia/audio/qaudiodevicefactory.cpp b/src/multimedia/audio/qaudiodevicefactory.cpp
index 96545b4..736630e 100644
--- a/src/multimedia/audio/qaudiodevicefactory.cpp
+++ b/src/multimedia/audio/qaudiodevicefactory.cpp
@@ -67,7 +67,8 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_LIBRARY
+
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QAudioEngineFactoryInterface_iid, QLatin1String("/audio"), Qt::CaseInsensitive))
#endif
@@ -138,8 +139,7 @@ QList<QAudioDeviceInfo> QAudioDeviceFactory::availableDevices(QAudio::Mode mode)
devices << QAudioDeviceInfo(QLatin1String("builtin"), handle, mode);
#endif
#endif
-
-#ifndef QT_NO_LIBRARY
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
QFactoryLoader* l = loader();
foreach (QString const& key, l->keys()) {
@@ -152,13 +152,12 @@ QList<QAudioDeviceInfo> QAudioDeviceFactory::availableDevices(QAudio::Mode mode)
delete plugin;
}
#endif
-
return devices;
}
QAudioDeviceInfo QAudioDeviceFactory::defaultInputDevice()
{
-#ifndef QT_NO_LIBRARY
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
QAudioEngineFactoryInterface* plugin = qobject_cast<QAudioEngineFactoryInterface*>(loader()->instance(QLatin1String("default")));
if (plugin) {
@@ -178,7 +177,7 @@ QAudioDeviceInfo QAudioDeviceFactory::defaultInputDevice()
QAudioDeviceInfo QAudioDeviceFactory::defaultOutputDevice()
{
-#ifndef QT_NO_LIBRARY
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
QAudioEngineFactoryInterface* plugin = qobject_cast<QAudioEngineFactoryInterface*>(loader()->instance(QLatin1String("default")));
if (plugin) {
@@ -206,15 +205,13 @@ QAbstractAudioDeviceInfo* QAudioDeviceFactory::audioDeviceInfo(const QString &re
return new QAudioDeviceInfoInternal(handle, mode);
#endif
#endif
-
-#ifndef QT_NO_LIBRARY
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
QAudioEngineFactoryInterface* plugin =
qobject_cast<QAudioEngineFactoryInterface*>(loader()->instance(realm));
if (plugin)
rc = plugin->createDeviceInfo(handle, mode);
#endif
-
return rc == 0 ? new QNullDeviceInfo() : rc;
}
@@ -238,14 +235,13 @@ QAbstractAudioInput* QAudioDeviceFactory::createInputDevice(QAudioDeviceInfo con
return new QAudioInputPrivate(deviceInfo.handle(), format);
#endif
#endif
-#ifndef QT_NO_LIBRARY
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
QAudioEngineFactoryInterface* plugin =
qobject_cast<QAudioEngineFactoryInterface*>(loader()->instance(deviceInfo.realm()));
if (plugin)
return plugin->createInput(deviceInfo.handle(), format);
#endif
-
return new QNullInputDevice();
}
@@ -259,15 +255,13 @@ QAbstractAudioOutput* QAudioDeviceFactory::createOutputDevice(QAudioDeviceInfo c
return new QAudioOutputPrivate(deviceInfo.handle(), format);
#endif
#endif
-
-#ifndef QT_NO_LIBRARY
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
QAudioEngineFactoryInterface* plugin =
qobject_cast<QAudioEngineFactoryInterface*>(loader()->instance(deviceInfo.realm()));
if (plugin)
return plugin->createOutput(deviceInfo.handle(), format);
#endif
-
return new QNullOutputDevice();
}
diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp
index 36270a7..f663dd2 100644
--- a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp
+++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp
@@ -62,6 +62,8 @@ QAudioDeviceInfoInternal::QAudioDeviceInfoInternal(QByteArray dev, QAudio::Mode
device = QLatin1String(dev);
this->mode = mode;
+
+ checkSurround();
}
QAudioDeviceInfoInternal::~QAudioDeviceInfoInternal()
@@ -389,6 +391,9 @@ void QAudioDeviceInfoInternal::updateLists()
}
channelz.append(1);
channelz.append(2);
+ if (surround40) channelz.append(4);
+ if (surround51) channelz.append(6);
+ if (surround71) channelz.append(8);
sizez.append(8);
sizez.append(16);
sizez.append(32);
@@ -483,4 +488,45 @@ QByteArray QAudioDeviceInfoInternal::defaultOutputDevice()
return devices.first();
}
+void QAudioDeviceInfoInternal::checkSurround()
+{
+ QList<QByteArray> devices;
+ surround40 = false;
+ surround51 = false;
+ surround71 = false;
+
+ void **hints, **n;
+ char *name, *descr, *io;
+
+ if(snd_device_name_hint(-1, "pcm", &hints) < 0)
+ return;
+
+ n = hints;
+
+ while (*n != NULL) {
+ name = snd_device_name_get_hint(*n, "NAME");
+ descr = snd_device_name_get_hint(*n, "DESC");
+ io = snd_device_name_get_hint(*n, "IOID");
+ if((name != NULL) && (descr != NULL)) {
+ QString deviceName = QLatin1String(name);
+ if (mode == QAudio::AudioOutput) {
+ if(deviceName.contains(QLatin1String("surround40")))
+ surround40 = true;
+ if(deviceName.contains(QLatin1String("surround51")))
+ surround51 = true;
+ if(deviceName.contains(QLatin1String("surround71")))
+ surround71 = true;
+ }
+ }
+ if(name != NULL)
+ free(name);
+ if(descr != NULL)
+ free(descr);
+ if(io != NULL)
+ free(io);
+ ++n;
+ }
+ snd_device_name_free_hint(hints);
+}
+
QT_END_NAMESPACE
diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h
index 6f9a459..8525980 100644
--- a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h
+++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.h
@@ -98,6 +98,11 @@ private:
bool open();
void close();
+ void checkSurround();
+ bool surround40;
+ bool surround51;
+ bool surround71;
+
QString device;
QAudio::Mode mode;
QAudioFormat nearest;
diff --git a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp
index aee0807..9e8b1bf 100644
--- a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp
+++ b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp
@@ -374,6 +374,11 @@ void QAudioDeviceInfoInternal::updateLists()
#endif
channelz.append(1);
channelz.append(2);
+ if (mode == QAudio::AudioOutput) {
+ channelz.append(4);
+ channelz.append(6);
+ channelz.append(8);
+ }
byteOrderz.append(QAudioFormat::LittleEndian);
diff --git a/src/multimedia/audio/qaudioinput_alsa_p.cpp b/src/multimedia/audio/qaudioinput_alsa_p.cpp
index c9a8b71..58669b3 100644
--- a/src/multimedia/audio/qaudioinput_alsa_p.cpp
+++ b/src/multimedia/audio/qaudioinput_alsa_p.cpp
@@ -120,7 +120,7 @@ int QAudioInputPrivate::xrun_recovery(int err)
if(err < 0)
reset = true;
else {
- bytesAvailable = bytesReady();
+ bytesAvailable = checkBytesReady();
if (bytesAvailable <= 0)
reset = true;
}
@@ -408,7 +408,7 @@ bool QAudioInputPrivate::open()
snd_pcm_start(handle);
// Step 5: Setup timer
- bytesAvailable = bytesReady();
+ bytesAvailable = checkBytesReady();
if(pullMode)
connect(audioSource,SIGNAL(readyRead()),this,SLOT(userFeed()));
@@ -437,19 +437,29 @@ void QAudioInputPrivate::close()
}
}
-int QAudioInputPrivate::bytesReady() const
+int QAudioInputPrivate::checkBytesReady()
{
if(resuming)
- return period_size;
-
- if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
- return 0;
- int frames = snd_pcm_avail_update(handle);
- if (frames < 0) return frames;
- if((int)frames > (int)buffer_frames)
- frames = buffer_frames;
+ bytesAvailable = period_size;
+ else if(deviceState != QAudio::ActiveState
+ && deviceState != QAudio::IdleState)
+ bytesAvailable = 0;
+ else {
+ int frames = snd_pcm_avail_update(handle);
+ if (frames < 0) {
+ bytesAvailable = frames;
+ } else {
+ if((int)frames > (int)buffer_frames)
+ frames = buffer_frames;
+ bytesAvailable = snd_pcm_frames_to_bytes(handle, frames);
+ }
+ }
+ return bytesAvailable;
+}
- return snd_pcm_frames_to_bytes(handle, frames);
+int QAudioInputPrivate::bytesReady() const
+{
+ return qMax(bytesAvailable, 0);
}
qint64 QAudioInputPrivate::read(char* data, qint64 len)
@@ -460,12 +470,12 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len)
if ( !handle )
return 0;
- bytesAvailable = bytesReady();
+ bytesAvailable = checkBytesReady();
if (bytesAvailable < 0) {
// bytesAvailable as negative is error code, try to recover from it.
xrun_recovery(bytesAvailable);
- bytesAvailable = bytesReady();
+ bytesAvailable = checkBytesReady();
if (bytesAvailable < 0) {
// recovery failed must stop and set error.
close();
@@ -639,11 +649,25 @@ bool QAudioInputPrivate::deviceReady()
InputPrivate* a = qobject_cast<InputPrivate*>(audioSource);
a->trigger();
}
- bytesAvailable = bytesReady();
+ bytesAvailable = checkBytesReady();
if(deviceState != QAudio::ActiveState)
return true;
+ if (bytesAvailable < 0) {
+ // bytesAvailable as negative is error code, try to recover from it.
+ xrun_recovery(bytesAvailable);
+ bytesAvailable = checkBytesReady();
+ if (bytesAvailable < 0) {
+ // recovery failed must stop and set error.
+ close();
+ errorState = QAudio::IOError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ return 0;
+ }
+ }
+
if(intervalTime && (timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
emit notify();
elapsedTimeOffset = timeStamp.elapsed() + elapsedTimeOffset - intervalTime;
diff --git a/src/multimedia/audio/qaudioinput_alsa_p.h b/src/multimedia/audio/qaudioinput_alsa_p.h
index c907019..52975a6 100644
--- a/src/multimedia/audio/qaudioinput_alsa_p.h
+++ b/src/multimedia/audio/qaudioinput_alsa_p.h
@@ -110,6 +110,7 @@ private slots:
bool deviceReady();
private:
+ int checkBytesReady();
int xrun_recovery(int err);
int setFormat();
bool open();
diff --git a/src/multimedia/audio/qaudioinput_win32_p.cpp b/src/multimedia/audio/qaudioinput_win32_p.cpp
index 14a1cf3..ece1c26 100644
--- a/src/multimedia/audio/qaudioinput_win32_p.cpp
+++ b/src/multimedia/audio/qaudioinput_win32_p.cpp
@@ -148,7 +148,7 @@ void QAudioInputPrivate::freeBlocks(WAVEHDR* blockArray)
for(int i = 0; i < count; i++) {
waveInUnprepareHeader(hWaveIn,blocks, sizeof(WAVEHDR));
- blocks+=sizeof(WAVEHDR);
+ blocks++;
}
HeapFree(GetProcessHeap(), 0, blockArray);
}
diff --git a/src/multimedia/audio/qaudiooutput_win32_p.cpp b/src/multimedia/audio/qaudiooutput_win32_p.cpp
index a8aeb41..99bada2 100644
--- a/src/multimedia/audio/qaudiooutput_win32_p.cpp
+++ b/src/multimedia/audio/qaudiooutput_win32_p.cpp
@@ -52,6 +52,53 @@
#include "qaudiooutput_win32_p.h"
+#ifndef SPEAKER_FRONT_LEFT
+ #define SPEAKER_FRONT_LEFT 0x00000001
+ #define SPEAKER_FRONT_RIGHT 0x00000002
+ #define SPEAKER_FRONT_CENTER 0x00000004
+ #define SPEAKER_LOW_FREQUENCY 0x00000008
+ #define SPEAKER_BACK_LEFT 0x00000010
+ #define SPEAKER_BACK_RIGHT 0x00000020
+ #define SPEAKER_FRONT_LEFT_OF_CENTER 0x00000040
+ #define SPEAKER_FRONT_RIGHT_OF_CENTER 0x00000080
+ #define SPEAKER_BACK_CENTER 0x00000100
+ #define SPEAKER_SIDE_LEFT 0x00000200
+ #define SPEAKER_SIDE_RIGHT 0x00000400
+ #define SPEAKER_TOP_CENTER 0x00000800
+ #define SPEAKER_TOP_FRONT_LEFT 0x00001000
+ #define SPEAKER_TOP_FRONT_CENTER 0x00002000
+ #define SPEAKER_TOP_FRONT_RIGHT 0x00004000
+ #define SPEAKER_TOP_BACK_LEFT 0x00008000
+ #define SPEAKER_TOP_BACK_CENTER 0x00010000
+ #define SPEAKER_TOP_BACK_RIGHT 0x00020000
+ #define SPEAKER_RESERVED 0x7FFC0000
+ #define SPEAKER_ALL 0x80000000
+#endif
+
+#ifndef _WAVEFORMATEXTENSIBLE_
+
+ #define _WAVEFORMATEXTENSIBLE_
+ typedef struct
+ {
+ WAVEFORMATEX Format; // Base WAVEFORMATEX data
+ union
+ {
+ WORD wValidBitsPerSample; // Valid bits in each sample container
+ WORD wSamplesPerBlock; // Samples per block of audio data; valid
+ // if wBitsPerSample=0 (but rarely used).
+ WORD wReserved; // Zero if neither case above applies.
+ } Samples;
+ DWORD dwChannelMask; // Positions of the audio channels
+ GUID SubFormat; // Format identifier GUID
+ } WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE, *LPPWAVEFORMATEXTENSIBLE;
+ typedef const WAVEFORMATEXTENSIBLE* LPCWAVEFORMATEXTENSIBLE;
+
+#endif
+
+#if !defined(WAVE_FORMAT_EXTENSIBLE)
+#define WAVE_FORMAT_EXTENSIBLE 0xFFFE
+#endif
+
//#define DEBUG_AUDIO 1
QT_BEGIN_NAMESPACE
@@ -146,7 +193,7 @@ void QAudioOutputPrivate::freeBlocks(WAVEHDR* blockArray)
for(int i = 0; i < count; i++) {
waveOutUnprepareHeader(hWaveOut,blocks, sizeof(WAVEHDR));
- blocks+=sizeof(WAVEHDR);
+ blocks++;
}
HeapFree(GetProcessHeap(), 0, blockArray);
}
@@ -258,15 +305,49 @@ bool QAudioOutputPrivate::open()
}
}
- if(waveOutOpen(&hWaveOut, devId, &wfx,
- (DWORD_PTR)&waveOutProc,
- (DWORD_PTR) this,
- CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
- errorState = QAudio::OpenError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
- qWarning("QAudioOutput: open error");
- return false;
+ if ( settings.channels() <= 2) {
+ if(waveOutOpen(&hWaveOut, devId, &wfx,
+ (DWORD_PTR)&waveOutProc,
+ (DWORD_PTR) this,
+ CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
+ errorState = QAudio::OpenError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ qWarning("QAudioOutput: open error");
+ return false;
+ }
+ } else {
+ WAVEFORMATEXTENSIBLE wfex;
+ wfex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
+ wfex.Format.nChannels = settings.channels();
+ wfex.Format.wBitsPerSample = settings.sampleSize();
+ wfex.Format.nSamplesPerSec = settings.frequency();
+ wfex.Format.nBlockAlign = wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
+ wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*wfex.Format.nBlockAlign;
+ wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
+ static const GUID _KSDATAFORMAT_SUBTYPE_PCM = {
+ 0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+ wfex.SubFormat=_KSDATAFORMAT_SUBTYPE_PCM;
+ wfex.Format.cbSize=22;
+
+ wfex.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
+ if (settings.channels() >= 4)
+ wfex.dwChannelMask |= SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT;
+ if (settings.channels() >= 6)
+ wfex.dwChannelMask |= SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY;
+ if (settings.channels() == 8)
+ wfex.dwChannelMask |= SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT;
+
+ if(waveOutOpen(&hWaveOut, devId, &wfex.Format,
+ (DWORD_PTR)&waveOutProc,
+ (DWORD_PTR) this,
+ CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
+ errorState = QAudio::OpenError;
+ deviceState = QAudio::StoppedState;
+ emit stateChanged(deviceState);
+ qWarning("QAudioOutput: open error");
+ return false;
+ }
}
totalTimeValue = 0;