From f49f8bdf06bbdf49c7586e6566d43e9b97cde2e6 Mon Sep 17 00:00:00 2001 From: Samuel Gomes <47574584+a740g@users.noreply.github.com> Date: Wed, 5 Oct 2022 02:33:44 +0530 Subject: [PATCH 1/3] Implement `_SNDPLAYCOPY` enhancement #185 --- internal/c/libqb/include/audio.h | 2 +- internal/c/parts/audio/audio.cpp | 25 +++++++++++++++++++++-- internal/c/parts/audio/out/src.c | 4 ++-- internal/c/qbx.cpp | 26 +----------------------- source/subs_functions/subs_functions.bas | 11 +++++----- 5 files changed, 32 insertions(+), 36 deletions(-) diff --git a/internal/c/libqb/include/audio.h b/internal/c/libqb/include/audio.h index ea71df423..8e53bd3f7 100644 --- a/internal/c/libqb/include/audio.h +++ b/internal/c/libqb/include/audio.h @@ -66,7 +66,7 @@ int32_t func__sndopen(qbs *fileName, qbs *requirements, int32_t passed); void sub__sndclose(int32_t handle); int32_t func__sndcopy(int32_t src_handle); void sub__sndplay(int32_t handle); -void sub__sndplaycopy(int32_t src_handle, double volume, int32_t passed); +void sub__sndplaycopy(int32_t src_handle, double volume, double x, double y, double z, int32_t passed); void sub__sndplayfile(qbs *fileName, int32_t sync, double volume, int32_t passed); void sub__sndpause(int32_t handle); int32_t func__sndplaying(int32_t handle); diff --git a/internal/c/parts/audio/audio.cpp b/internal/c/parts/audio/audio.cpp index 7481def2d..9a9117625 100644 --- a/internal/c/parts/audio/audio.cpp +++ b/internal/c/parts/audio/audio.cpp @@ -1523,8 +1523,11 @@ void sub__sndplay(int32_t handle) { /// /// A sound handle to copy /// The volume at which the sound should be played (0.0 - 1.0) +/// x distance values go from left (negative) to right (positive) +/// y distance values go from below (negative) to above (positive). +/// z distance values go from behind (negative) to in front (positive). /// How many parameters were passed? -void sub__sndplaycopy(int32_t src_handle, double volume, int32_t passed) { +void sub__sndplaycopy(int32_t src_handle, double volume, double x, double y, double z, int32_t passed) { // We are simply going to use sndcopy, then setup some stuff like volume and autokill and then use sndplay // We are not checking if the audio engine was initialized because if not we'll get an invalid handle anyway int32_t dst_handle = func__sndcopy(src_handle); @@ -1532,9 +1535,27 @@ void sub__sndplaycopy(int32_t src_handle, double volume, int32_t passed) { // Check if we succeeded and then proceed if (dst_handle > 0) { // Set the volume if requested - if (passed) + if (passed & 1) ma_sound_set_volume(&audioEngine.soundHandles[dst_handle]->maSound, volume); + if (passed & 4 || passed & 8) { // If y or z or both are passed + ma_sound_set_spatialization_enabled(&audioEngine.soundHandles[dst_handle]->maSound, MA_TRUE); // Enable 3D spatialization + + // Set values of x, y, z to 0 if these were not passed + if (!(passed & 2)) + x = 0.0; + if (!(passed & 4)) + y = 0.0; + if (!(passed & 8)) + z = 0.0; + + ma_sound_set_position(&audioEngine.soundHandles[dst_handle]->maSound, x, y, z); // Use full 3D positioning + } else if (passed & 2) { + ma_sound_set_spatialization_enabled(&audioEngine.soundHandles[dst_handle]->maSound, MA_FALSE); // Disable spatialization for better stereo sound + ma_sound_set_pan_mode(&audioEngine.soundHandles[dst_handle]->maSound, ma_pan_mode_pan); // Set true panning + ma_sound_set_pan(&audioEngine.soundHandles[dst_handle]->maSound, x); // Just use stereo panning + } + sub__sndplay(dst_handle); // Play the sound audioEngine.soundHandles[dst_handle]->autoKill = true; // Set to auto kill } diff --git a/internal/c/parts/audio/out/src.c b/internal/c/parts/audio/out/src.c index 7c951d12e..0cd25a71a 100644 --- a/internal/c/parts/audio/out/src.c +++ b/internal/c/parts/audio/out/src.c @@ -1149,7 +1149,7 @@ void sub__sndclose(int32 handle) { //"macros" -void sub__sndplaycopy(int32 handle, double volume, int32 passed) { +void sub__sndplaycopy(int32 handle, double volume, double x, double y, double z, int32 passed) { if (new_error) return; sndsetup(); @@ -1157,7 +1157,7 @@ void sub__sndplaycopy(int32 handle, double volume, int32 passed) { handle2 = func__sndcopy(handle); if (!handle2) return; // an error has already happened - if (passed) { + if (passed & 1) { sub__sndvol(handle2, volume); if (sub__sndvol_error) { sub__sndclose(handle2); diff --git a/internal/c/qbx.cpp b/internal/c/qbx.cpp index c79b0fe3e..186270200 100755 --- a/internal/c/qbx.cpp +++ b/internal/c/qbx.cpp @@ -1,4 +1,5 @@ #include "common.h" +#include "audio.h" extern int32 func__cinp(int32 toggle, int32 passed); // Console INP scan code reader @@ -216,11 +217,6 @@ extern void sub__maptriangle(int32 cull_options, float sx1, float sy1, int32 smooth_options, int32 passed); extern void sub__depthbuffer(int32 options, int32 dst, int32 passed); extern int32 func_play(int32 ignore); -extern int32 func__sndrate(); -extern int32 func__sndopenraw(); -extern void sub__sndrawdone(int32 handle, int32 passed); -extern void sub__sndraw(float left, float right, int32 handle, int32 passed); -extern double func__sndrawlen(int32 handle, int32 passed); extern void sub_paletteusing(void *element, int32 bits); extern int64 func_read_int64(uint8 *data, ptrszint *data_offset, ptrszint data_size); @@ -581,26 +577,6 @@ extern qbs *func_input(int32 n, int32 i, int32 passed); extern double func_sqr(double value); extern void sub_beep(); extern void snd_check(); -extern int32 func__sndraw(uint8 *data, uint32 bytes); -extern int32 func__sndopen(qbs *filename, qbs *requirements, int32 passed); -extern double func__sndlen(int32 handle); -extern void sub__sndlimit(int32 handle, double limit); -extern void sub__sndstop(int32 handle); -extern void sub__sndsetpos(int32 handle, double sec); -extern double func__sndgetpos(int32 handle); -extern void sub__sndbal(int32 handle, double x, double y, double z, - int32 channel, int32 passed); -extern void sub__sndplay(int32 handle); -extern void sub__sndloop(int32 handle); -extern int32 func__sndcopy(int32 handle); -extern void sub__sndvol(int32 handle, float volume); -extern void sub__sndpause(int32 handle); -extern int32 func__sndpaused(int32 handle); -extern int32 func__sndplaying(int32 handle); -extern void sub__sndclose(int32 handle); -extern void sub__sndplayfile(qbs *filename, int32 sync, double volume, - int32 passed); -extern void sub__sndplaycopy(int32 handle, double volume, int32 passed); extern qbs *func_command(int32 index, int32 passed); extern int32 func__commandcount(); extern void sub_kill(qbs *str); diff --git a/source/subs_functions/subs_functions.bas b/source/subs_functions/subs_functions.bas index f9f5f3133..aade2511c 100644 --- a/source/subs_functions/subs_functions.bas +++ b/source/subs_functions/subs_functions.bas @@ -1929,10 +1929,10 @@ clearid id.n = qb64prefix$ + "SndPlayCopy": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 2 id.callname = "sub__sndplaycopy" -id.args = 2 -id.arg = MKL$(ULONGTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) -id.specialformat = "?[,?]" -id.hr_syntax = "_SNDPLAYCOPY handle&[, volume!]" +id.args = 5 +id.arg = MKL$(ULONGTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) +id.specialformat = "?[,[?][,[?][,[?][,[?]]]]]" +id.hr_syntax = "_SNDPLAYCOPY handle&[, volume!][, x!][, y!][, z!]" regid clearid @@ -2018,10 +2018,9 @@ id.callname = "sub__sndbal" id.args = 5 id.arg = MKL$(ULONGTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(ULONGTYPE - ISPOINTER) id.specialformat = "?,[?][,[?][,[?][,[?]]]]" -id.hr_syntax = "_SNDBAL handle&[, x!][, y!][, z!][, channel&]]" +id.hr_syntax = "_SNDBAL handle&[, x!][, y!][, z!][, channel&]" regid - clearid id.n = qb64prefix$ + "SndVol": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 2 From 7e63a684073c36ff21d079ec1ba5453c2ae1cddd Mon Sep 17 00:00:00 2001 From: Samuel Gomes <47574584+a740g@users.noreply.github.com> Date: Wed, 5 Oct 2022 06:31:46 +0530 Subject: [PATCH 2/3] Simplify `sub__sndplaycopy` --- internal/c/parts/audio/audio.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/internal/c/parts/audio/audio.cpp b/internal/c/parts/audio/audio.cpp index 9a9117625..fd6eba187 100644 --- a/internal/c/parts/audio/audio.cpp +++ b/internal/c/parts/audio/audio.cpp @@ -1540,16 +1540,7 @@ void sub__sndplaycopy(int32_t src_handle, double volume, double x, double y, dou if (passed & 4 || passed & 8) { // If y or z or both are passed ma_sound_set_spatialization_enabled(&audioEngine.soundHandles[dst_handle]->maSound, MA_TRUE); // Enable 3D spatialization - - // Set values of x, y, z to 0 if these were not passed - if (!(passed & 2)) - x = 0.0; - if (!(passed & 4)) - y = 0.0; - if (!(passed & 8)) - z = 0.0; - - ma_sound_set_position(&audioEngine.soundHandles[dst_handle]->maSound, x, y, z); // Use full 3D positioning + ma_sound_set_position(&audioEngine.soundHandles[dst_handle]->maSound, x, y, z); // Use full 3D positioning } else if (passed & 2) { ma_sound_set_spatialization_enabled(&audioEngine.soundHandles[dst_handle]->maSound, MA_FALSE); // Disable spatialization for better stereo sound ma_sound_set_pan_mode(&audioEngine.soundHandles[dst_handle]->maSound, ma_pan_mode_pan); // Set true panning @@ -1559,6 +1550,8 @@ void sub__sndplaycopy(int32_t src_handle, double volume, double x, double y, dou sub__sndplay(dst_handle); // Play the sound audioEngine.soundHandles[dst_handle]->autoKill = true; // Set to auto kill } + + AUDIO_DEBUG_PRINT("Playing sound copy %i: volume %lf, 3D (%lf, %lf, %lf)", dst_handle, volume, x, y, z); } /// From a2e77d7557c8c9bfd541f7a31c81ba868668367e Mon Sep 17 00:00:00 2001 From: Samuel Gomes <47574584+a740g@users.noreply.github.com> Date: Wed, 5 Oct 2022 15:28:04 +0530 Subject: [PATCH 3/3] Only change `_SNDBAL` stereo panning if `x` is passed. Mimic old OpenAL behavior. --- internal/c/parts/audio/audio.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/c/parts/audio/audio.cpp b/internal/c/parts/audio/audio.cpp index fd6eba187..7805640fe 100644 --- a/internal/c/parts/audio/audio.cpp +++ b/internal/c/parts/audio/audio.cpp @@ -1538,10 +1538,10 @@ void sub__sndplaycopy(int32_t src_handle, double volume, double x, double y, dou if (passed & 1) ma_sound_set_volume(&audioEngine.soundHandles[dst_handle]->maSound, volume); - if (passed & 4 || passed & 8) { // If y or z or both are passed - ma_sound_set_spatialization_enabled(&audioEngine.soundHandles[dst_handle]->maSound, MA_TRUE); // Enable 3D spatialization - ma_sound_set_position(&audioEngine.soundHandles[dst_handle]->maSound, x, y, z); // Use full 3D positioning - } else if (passed & 2) { + if (passed & 4 || passed & 8) { // If y or z or both are passed + ma_sound_set_spatialization_enabled(&audioEngine.soundHandles[dst_handle]->maSound, MA_TRUE); // Enable 3D spatialization + ma_sound_set_position(&audioEngine.soundHandles[dst_handle]->maSound, x, y, z); // Use full 3D positioning + } else if (passed & 2) { // If x is passed ma_sound_set_spatialization_enabled(&audioEngine.soundHandles[dst_handle]->maSound, MA_FALSE); // Disable spatialization for better stereo sound ma_sound_set_pan_mode(&audioEngine.soundHandles[dst_handle]->maSound, ma_pan_mode_pan); // Set true panning ma_sound_set_pan(&audioEngine.soundHandles[dst_handle]->maSound, x); // Just use stereo panning @@ -1693,8 +1693,8 @@ void sub__sndbal(int32_t handle, double x, double y, double z, int32_t channel, if (!(passed & 4)) z = v.z; - ma_sound_set_position(&audioEngine.soundHandles[handle]->maSound, x, y, z); // Use full 3D positioning - } else { + ma_sound_set_position(&audioEngine.soundHandles[handle]->maSound, x, y, z); // Use full 3D positioning + } else if (passed & 1) { // Only bother if x is passed ma_sound_set_spatialization_enabled(&audioEngine.soundHandles[handle]->maSound, MA_FALSE); // Disable spatialization for better stereo sound ma_sound_set_pan_mode(&audioEngine.soundHandles[handle]->maSound, ma_pan_mode_pan); // Set true panning ma_sound_set_pan(&audioEngine.soundHandles[handle]->maSound, x); // Just use stereo panning