From 8ede9fb39be383fc1e0ad7f129f0f3c9feabcad4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 10 Mar 2015 15:50:30 -0700 Subject: [PATCH] fix stereo to stereo resampling --- .../utilities/diagnostics/orbitingSound.js | 12 +++++----- libraries/audio-client/src/AudioClient.cpp | 24 +++++++++++++------ libraries/audio/src/AudioInjector.h | 6 ++++- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/examples/utilities/diagnostics/orbitingSound.js b/examples/utilities/diagnostics/orbitingSound.js index 1af6fab827..370ed38595 100644 --- a/examples/utilities/diagnostics/orbitingSound.js +++ b/examples/utilities/diagnostics/orbitingSound.js @@ -20,11 +20,11 @@ var trailingLoudness = 0.0; var soundClip = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Tabla+Loops/Tabla1.wav"); var properties = { - type: "Box", - position: orbitCenter, - dimensions: { x: 0.25, y: 0.25, z: 0.25 }, - color: { red: 100, green: 0, blue : 0 } - }; + type: "Box", + position: orbitCenter, + dimensions: { x: 0.25, y: 0.25, z: 0.25 }, + color: { red: 100, green: 0, blue : 0 } +}; var objectId = Entities.addEntity(properties); var sound = Audio.playSound(soundClip, { position: orbitCenter, loop: true, volume: 0.5 }); @@ -34,7 +34,7 @@ function update(deltaTime) { currentPosition = { x: orbitCenter.x + Math.cos(time * SPEED) * RADIUS, y: orbitCenter.y, z: orbitCenter.z + Math.sin(time * SPEED) * RADIUS }; trailingLoudness = 0.9 * trailingLoudness + 0.1 * sound.loudness; Entities.editEntity( objectId, { position: currentPosition, color: { red: Math.min(trailingLoudness * 2000, 255), green: 0, blue: 0 } } ); - sound.setOptions({ position: currentPosition }); + sound.options = { position: currentPosition }; } Script.scriptEnding.connect(function() { diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 6e068e0635..c083fbc085 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -320,6 +320,7 @@ bool adjustedFormatForAudioDevice(const QAudioDeviceInfo& audioDevice, #ifdef Q_OS_ANDROID adjustedAudioFormat.setSampleRate(FORTY_FOUR); #else + const int HALF_FORTY_FOUR = FORTY_FOUR / 2; if (audioDevice.supportedSampleRates().contains(AudioConstants::SAMPLE_RATE * 2)) { @@ -397,18 +398,24 @@ soxr_error_t possibleResampling(soxr_t resampler, numSourceSamples, sourceAudioFormat, destinationAudioFormat); - qDebug() << "resample from" << sourceAudioFormat << "to" << destinationAudioFormat - << "from" << numChannelCoversionSamples << "to" << numDestinationSamples; - resampleError = soxr_process(resampler, channelConversionSamples, numChannelCoversionSamples, NULL, destinationSamples, numDestinationSamples, NULL); delete[] channelConversionSamples; } else { + + unsigned int numAdjustedSourceSamples = numSourceSamples; + unsigned int numAdjustedDestinationSamples = numDestinationSamples; + + if (sourceAudioFormat.channelCount() == 2 && destinationAudioFormat.channelCount() == 2) { + numAdjustedSourceSamples /= 2; + numAdjustedDestinationSamples /= 2; + } + resampleError = soxr_process(resampler, - sourceSamples, numSourceSamples, NULL, - destinationSamples, numDestinationSamples, NULL); + sourceSamples, numAdjustedSourceSamples, NULL, + destinationSamples, numAdjustedDestinationSamples, NULL); } return resampleError; @@ -429,9 +436,12 @@ soxr_t soxrResamplerFromInputFormatToOutputFormat(const QAudioFormat& sourceAudi // setup soxr_quality_spec_t for quality options soxr_quality_spec_t qualitySpec = soxr_quality_spec(SOXR_MQ, 0); + int channelCount = (sourceAudioFormat.channelCount() == 2 && destinationAudioFormat.channelCount() == 2) + ? 2 : 1; + soxr_t newResampler = soxr_create(sourceAudioFormat.sampleRate(), destinationAudioFormat.sampleRate(), - 1, + channelCount, &soxrError, &inputToNetworkSpec, &qualitySpec, 0); if (soxrError) { @@ -1136,7 +1146,7 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDevice if (!outputDeviceInfo.isNull()) { qDebug() << "The audio output device " << outputDeviceInfo.deviceName() << "is available."; _outputAudioDeviceName = outputDeviceInfo.deviceName().trimmed(); - + if (adjustedFormatForAudioDevice(outputDeviceInfo, _desiredOutputFormat, _outputFormat)) { qDebug() << "The format to be used for audio output is" << _outputFormat; diff --git a/libraries/audio/src/AudioInjector.h b/libraries/audio/src/AudioInjector.h index 25d0c1699d..ca39dcbdc4 100644 --- a/libraries/audio/src/AudioInjector.h +++ b/libraries/audio/src/AudioInjector.h @@ -30,6 +30,8 @@ class AbstractAudioInterface; class AudioInjector : public QObject { Q_OBJECT + + Q_PROPERTY(AudioInjectorOptions options WRITE setOptions READ getOptions) public: AudioInjector(QObject* parent); AudioInjector(Sound* sound, const AudioInjectorOptions& injectorOptions); @@ -51,7 +53,9 @@ public slots: void triggerDeleteAfterFinish() { _shouldDeleteAfterFinish = true; } void stopAndDeleteLater(); - void setOptions(AudioInjectorOptions& options) { _options = options; } + const AudioInjectorOptions& getOptions() const { return _options; } + void setOptions(const AudioInjectorOptions& options) { _options = options; } + void setCurrentSendPosition(int currentSendPosition) { _currentSendPosition = currentSendPosition; } float getLoudness() const { return _loudness; } bool isPlaying() const { return !_isFinished; }