Split audio into stream/ and mixer/ subdirs, fix resulting build breaks

Reorganizes src/dusk/audio/: individual stream implementations
(audiostream, audiostreampcm, audiostreammp3, audiostreammp3decodersw)
move into audio/stream/, and a new audio/mixer/ holds a channel-based
playback queue (audiomixer.c/.h) for future use - not yet wired into
the engine.

Fixes needed to keep the tree buildable after the move:
 - A stray duplicate of audiostreammp3decodersw.c/.h was left at the old
   flat path; removed in favor of the canonical copy in stream/.
 - Updated every #include "audio/audiostream*.h" and the two platform
   CMakeLists.txt (dusklinux, duskdolphin) that still pointed at the old
   flat location.
 - audiomixer.c/.h didn't compile: audiomixerqueue_t was referenced but
   never defined (audiomixerchanneldata_t has the matching fields), a
   trailing comma in audioMixerPlayLooped's parameter list is illegal in
   C, and `file` was declared as an array of pointers instead of a char
   buffer.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
2026-09-02 09:32:41 -05:00
co-authored by Claude Sonnet 5
parent 62c081ecf2
commit 3ee0a53688
22 changed files with 242 additions and 16 deletions
+4 -3
View File
@@ -7,7 +7,8 @@
target_sources(${DUSK_LIBRARY_TARGET_NAME} target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC PUBLIC
audio.c audio.c
audiostream.c
audiostreampcm.c
audiostreammp3.c
) )
# Subdirs
add_subdirectory(mixer)
add_subdirectory(stream)
+1 -1
View File
@@ -7,7 +7,7 @@
#pragma once #pragma once
#include "dusk.h" #include "dusk.h"
#include "audio/audiostream.h" #include "audio/stream/audiostream.h"
#include "audio/audioplatform.h" #include "audio/audioplatform.h"
#ifndef audioPlatformInit #ifndef audioPlatformInit
+10
View File
@@ -0,0 +1,10 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
audiomixer.c
)
+94
View File
@@ -0,0 +1,94 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "audiomixer.h"
#include "util/memory.h"
#include "util/string.h"
#include "assert/assert.h"
audiomixer_t AUDIO_MIXER;
errorret_t audioMixerInit() {
memoryZero(&AUDIO_MIXER, sizeof(audiomixer_t));
errorOk();
}
errorret_t audioMixerUpdate() {
// For each channel.
audiomixerchannel_t channel = 0;
do {
audiomixerchanneldata_t *queue = &AUDIO_MIXER.queue[channel];
// File queued?
if(queue->file[0] == '\0') {
channel++;
continue;
}
// Stop this channel
audioMixerStop(channel);
// Get the file
// TODO: Loading?
// assetentry_t *entry = assetLock(queue->file, ASSET_LOADER_TYPE_WAV, NULL);
printf("Playing %s on channel %d\n", queue->file, channel);
} while(channel < AUDIO_MIXER_CHANNEL_COUNT);
errorOk();
}
void audioMixerPlay(
const char_t *file,
const audiomixerchannel_t channel,
const uint8_t volume,
const int8_t pan
) {
audioMixerPlayLooped(file, channel, volume, pan, 0, 0.0f, 0.0f);
}
void audioMixerPlayLooped(
const char_t *file,
const audiomixerchannel_t channel,
const uint8_t volume,
const int8_t pan,
const uint8_t loopCount,
const float_t loopStart,
const float_t loopTo
) {
assertStrLenMin(file, 1, "File is required, to stop use audioMixerStop");
assertTrue(channel < AUDIO_MIXER_CHANNEL_COUNT, "Channel is out of range");
assertTrue(volume <= 0xFF, "Volume is out of range");
assertTrue(volume > 0, "Volume must be greater than 0");
assertTrue(loopStart >= 0.0f, "Loop start incorrect");
assertTrue(loopTo >= 0.0f, "Loop to incorrect");
audiomixerchanneldata_t *queue = &AUDIO_MIXER.queue[channel];
stringCopy(queue->file, file, AUDIO_PATH_MAX);
queue->volume = volume;
queue->pan = pan;
queue->loopCount = loopCount;
queue->loopStart = loopStart;
queue->loopTo = loopTo;
}
void audioMixerStop(const audiomixerchannel_t channel) {
assertTrue(channel < AUDIO_MIXER_CHANNEL_COUNT, "Channel is out of range");
printf("Stopping channel %d\n", channel);
}
errorret_t audioMixerDispose() {
audiomixerchannel_t channel = 0;
do {
audioMixerStop(channel);
channel++;
} while(channel < AUDIO_MIXER_CHANNEL_COUNT);
errorOk();
}
+109
View File
@@ -0,0 +1,109 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "asset/asset.h"
typedef enum {
AUDIO_MIXER_CHANNEL_BGM_0,
AUDIO_MIXER_CHANNEL_VOICE_0,
AUDIO_MIXER_CHANNEL_VOICE_1,
AUDIO_MIXER_CHANNEL_SFX_0,
AUDIO_MIXER_CHANNEL_SFX_1,
AUDIO_MIXER_CHANNEL_SFX_2,
AUDIO_MIXER_CHANNEL_SFX_3,
AUDIO_MIXER_CHANNEL_COUNT
} audiomixerchannel_t;
#define AUDIO_PATH_MAX 256
typedef struct {
assetentry_t *asset;
char_t file[AUDIO_PATH_MAX];
uint8_t volume;
int8_t pan;
uint8_t loopCount;
float_t loopStart;
float_t loopTo;
} audiomixerchanneldata_t;
typedef struct {
audiomixerchanneldata_t queue[AUDIO_MIXER_CHANNEL_COUNT];
uint8_t fade[AUDIO_MIXER_CHANNEL_COUNT];
} audiomixer_t;
extern audiomixer_t AUDIO_MIXER;
/**
* Initializes the audio mixer.
*/
errorret_t audioMixerInit();
/**
* Updates the audio mixer.
*/
errorret_t audioMixerUpdate();
/**
* Same as audioMixerPlayLooped() but with no looping.
*
* @param file File to be played.
* @param channel Channel you want to play this sound on.
* @param volume Volume of the sound, from 0 (silent) to 0xFF (loudest).
* @param pan Stereo panning of the sound, from AUDIO_STREAM_LEFT to
* AUDIO_STREAM_RIGHT.
*/
void audioMixerPlay(
const char_t *file,
const audiomixerchannel_t channel,
const uint8_t volume,
const int8_t pan
);
/**
* Queues a sound to be played on the next audio mixer update, which occurs at
* the end of each frame.
*
* Mixer channels can only hold one voice (audio stream) at a time. If you try
* to queue multiple sounds on the same channel only the last one will be played
* and will stop any actively playing on that channel currently.
*
* Volume is also mixed based on the channel, so supplying volume 0xFF is then
* multiplied by the channel's volume, e.g. 0xDD*0xFF = 0xDD.
*
* @param file File to be played.
* @param channel Channel you want to play this sound on.
* @param volume Volume of the sound, from 0 (silent) to 0xFF (loudest).
* @param pan Stereo panning of the sound, from AUDIO_STREAM_LEFT to
* AUDIO_STREAM_RIGHT.
* @param loopCount How many times to loop the sound, 0 for infinite looping.
* @param loopStart Where the loop segment ends, in seconds, or -1 to loop
* the whole stream (the default).
* @param loopTo Where the loop segment starts, in seconds.
*/
void audioMixerPlayLooped(
const char_t *file,
const audiomixerchannel_t channel,
const uint8_t volume,
const int8_t pan,
const uint8_t loopCount,
const float_t loopStart,
const float_t loopTo
);
/**
* Stops playing sound on the given channel.
*
* @param channel Channel to stop.
*/
void audioMixerStop(const audiomixerchannel_t channel);
/**
* Disposes the audio mixer.
*/
errorret_t audioMixerDispose();
+12
View File
@@ -0,0 +1,12 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
audiostream.c
audiostreampcm.c
audiostreammp3.c
)
@@ -6,8 +6,8 @@
*/ */
#pragma once #pragma once
#include "audio/audiostreampcm.h" #include "audio/stream/audiostreampcm.h"
#include "audio/audiostreammp3.h" #include "audio/stream/audiostreammp3.h"
#include "audio/audiostreamplatform.h" #include "audio/audiostreamplatform.h"
#include "asset/loader/assetentry.h" #include "asset/loader/assetentry.h"
@@ -7,7 +7,7 @@
#define MINIMP3_IMPLEMENTATION #define MINIMP3_IMPLEMENTATION
#include "audiostreammp3decodersw.h" #include "audiostreammp3decodersw.h"
#include "audio/audiostream.h" #include "audiostream.h"
#include "assert/assert.h" #include "assert/assert.h"
#include "util/memory.h" #include "util/memory.h"
+1 -1
View File
@@ -25,5 +25,5 @@ endif()
target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PRIVATE minimp3) target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PRIVATE minimp3)
target_sources(${DUSK_LIBRARY_TARGET_NAME} target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC PUBLIC
"${DUSK_SOURCES_DIR}/dusk/audio/audiostreammp3decodersw.c" "${DUSK_SOURCES_DIR}/dusk/audio/stream/audiostreammp3decodersw.c"
) )
+1 -1
View File
@@ -6,7 +6,7 @@
*/ */
#include "audiostreamdolphin.h" #include "audiostreamdolphin.h"
#include "audio/audiostream.h" #include "audio/stream/audiostream.h"
#include "assert/assert.h" #include "assert/assert.h"
#include "util/memory.h" #include "util/memory.h"
#include "util/math.h" #include "util/math.h"
@@ -13,4 +13,4 @@
// audiostreamdolphin.c already owns - not a fit here), so Dolphin uses the // audiostreamdolphin.c already owns - not a fit here), so Dolphin uses the
// same shared minimp3-based software backend as Linux - see that header's // same shared minimp3-based software backend as Linux - see that header's
// own documentation for the actual struct/interface. // own documentation for the actual struct/interface.
#include "audio/audiostreammp3decodersw.h" #include "audio/stream/audiostreammp3decodersw.h"
+1 -1
View File
@@ -20,5 +20,5 @@ endif()
target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC minimp3) target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC minimp3)
target_sources(${DUSK_LIBRARY_TARGET_NAME} target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC PUBLIC
"${DUSK_SOURCES_DIR}/dusk/audio/audiostreammp3decodersw.c" "${DUSK_SOURCES_DIR}/dusk/audio/stream/audiostreammp3decodersw.c"
) )
+1 -1
View File
@@ -6,7 +6,7 @@
*/ */
#include "audiostreamlinux.h" #include "audiostreamlinux.h"
#include "audio/audiostream.h" #include "audio/stream/audiostream.h"
#include "assert/assert.h" #include "assert/assert.h"
#include "util/memory.h" #include "util/memory.h"
#include "util/math.h" #include "util/math.h"
+1 -1
View File
@@ -10,4 +10,4 @@
// Linux has no hardware MP3 decoder to prefer, so it uses the shared // Linux has no hardware MP3 decoder to prefer, so it uses the shared
// minimp3-based software backend (also used by Dolphin) - see that // minimp3-based software backend (also used by Dolphin) - see that
// header's own documentation for the actual struct/interface. // header's own documentation for the actual struct/interface.
#include "audio/audiostreammp3decodersw.h" #include "audio/stream/audiostreammp3decodersw.h"
+1 -1
View File
@@ -6,7 +6,7 @@
*/ */
#include "audiostreammp3decoder.h" #include "audiostreammp3decoder.h"
#include "audio/audiostream.h" #include "audio/stream/audiostream.h"
#include "assert/assert.h" #include "assert/assert.h"
#include "util/memory.h" #include "util/memory.h"
#include <pspmp3.h> #include <pspmp3.h>
+1 -1
View File
@@ -6,7 +6,7 @@
*/ */
#include "audiostreampsp.h" #include "audiostreampsp.h"
#include "audio/audiostream.h" #include "audio/stream/audiostream.h"
#include "assert/assert.h" #include "assert/assert.h"
#include "util/memory.h" #include "util/memory.h"
#include "util/math.h" #include "util/math.h"