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