From 622a1e30688982863eb73ef1f5edc229c2f5db6f Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 1 Jun 2015 21:19:42 -0700 Subject: [PATCH 1/2] Pitch-shift collision sounds, and make entities-renderer depend on soxr. --- libraries/entities-renderer/CMakeLists.txt | 6 +++++ .../src/EntityTreeRenderer.cpp | 26 ++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/libraries/entities-renderer/CMakeLists.txt b/libraries/entities-renderer/CMakeLists.txt index a94bfb5f97..394d156252 100644 --- a/libraries/entities-renderer/CMakeLists.txt +++ b/libraries/entities-renderer/CMakeLists.txt @@ -17,4 +17,10 @@ find_package(PolyVox REQUIRED) target_include_directories(${TARGET_NAME} SYSTEM PUBLIC ${POLYVOX_INCLUDE_DIRS}) target_link_libraries(${TARGET_NAME} ${POLYVOX_LIBRARIES}) +# for changing the pitch of collision sounds +add_dependency_external_projects(soxr) +find_package(Soxr REQUIRED) +target_link_libraries(${TARGET_NAME} ${SOXR_LIBRARIES}) +target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${SOXR_INCLUDE_DIRS}) + link_hifi_libraries(shared gpu script-engine render-utils) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 8f034409ae..e3680d4614 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include "EntityTreeRenderer.h" @@ -1158,7 +1159,30 @@ void EntityTreeRenderer::playEntityCollisionSound(const QUuid& myNodeID, EntityT options.stereo = sound->isStereo(); options.position = position; options.volume = volume; - AudioInjector* injector = new AudioInjector(sound.data(), options); + + // Shift the pitch down by ln(1 + (size / COLLISION_SIZE_FOR_STANDARD_PITCH)) / ln(2) + const float COLLISION_SIZE_FOR_STANDARD_PITCH = 0.2f; + QByteArray samples = sound->getByteArray(); + soxr_io_spec_t spec = soxr_io_spec(SOXR_INT16_I, SOXR_INT16_I); + soxr_quality_spec_t qualitySpec = soxr_quality_spec(SOXR_MQ, 0); + const int channelCount = sound->isStereo() ? 2 : 1; + const float factor = log(1.0f + (entity->getMaximumAACube().getLargestDimension() / COLLISION_SIZE_FOR_STANDARD_PITCH)) / log(2); + const int HIFI_SAMPLE_RATE = 24000; //AudioConstants::SAMPLE_RATE + const int resampledRate = HIFI_SAMPLE_RATE * factor; + const int nInputSamples = samples.size() / sizeof(int16_t); + const int nOutputSamples = nInputSamples * factor; + QByteArray resampled(nOutputSamples * sizeof(int16_t), '\0'); + const int16_t* receivedSamples = reinterpret_cast(samples.data()); + soxr_error_t soxError = soxr_oneshot(HIFI_SAMPLE_RATE, resampledRate, channelCount, + receivedSamples, nInputSamples, NULL, + reinterpret_cast(resampled.data()), nOutputSamples, NULL, + &spec, &qualitySpec, 0); + if (soxError) { + qCDebug(entitiesrenderer) << "Unable to resample" << collisionSoundURL << "from" << nInputSamples << "@" << HIFI_SAMPLE_RATE << "to" << nOutputSamples << "@" << resampledRate; + resampled = samples; + } + + AudioInjector* injector = new AudioInjector(resampled, options); injector->setLocalAudioInterface(_localAudioInterface); injector->triggerDeleteAfterFinish(); QThread* injectorThread = new QThread(); From 0837c016c52237ca6dcffdac98b8ca4d514bf4af Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 2 Jun 2015 09:18:45 -0700 Subject: [PATCH 2/2] Update constant to use AudioConstants.h --- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index e3680d4614..23e504bfb8 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include "EntityTreeRenderer.h" @@ -1167,18 +1168,18 @@ void EntityTreeRenderer::playEntityCollisionSound(const QUuid& myNodeID, EntityT soxr_quality_spec_t qualitySpec = soxr_quality_spec(SOXR_MQ, 0); const int channelCount = sound->isStereo() ? 2 : 1; const float factor = log(1.0f + (entity->getMaximumAACube().getLargestDimension() / COLLISION_SIZE_FOR_STANDARD_PITCH)) / log(2); - const int HIFI_SAMPLE_RATE = 24000; //AudioConstants::SAMPLE_RATE - const int resampledRate = HIFI_SAMPLE_RATE * factor; + const int standardRate = AudioConstants::SAMPLE_RATE; + const int resampledRate = standardRate * factor; const int nInputSamples = samples.size() / sizeof(int16_t); const int nOutputSamples = nInputSamples * factor; QByteArray resampled(nOutputSamples * sizeof(int16_t), '\0'); const int16_t* receivedSamples = reinterpret_cast(samples.data()); - soxr_error_t soxError = soxr_oneshot(HIFI_SAMPLE_RATE, resampledRate, channelCount, + soxr_error_t soxError = soxr_oneshot(standardRate, resampledRate, channelCount, receivedSamples, nInputSamples, NULL, reinterpret_cast(resampled.data()), nOutputSamples, NULL, &spec, &qualitySpec, 0); if (soxError) { - qCDebug(entitiesrenderer) << "Unable to resample" << collisionSoundURL << "from" << nInputSamples << "@" << HIFI_SAMPLE_RATE << "to" << nOutputSamples << "@" << resampledRate; + qCDebug(entitiesrenderer) << "Unable to resample" << collisionSoundURL << "from" << nInputSamples << "@" << standardRate << "to" << nOutputSamples << "@" << resampledRate; resampled = samples; }