From 07509f83f91c412f9150c52b4467429ac46eefe2 Mon Sep 17 00:00:00 2001 From: Michael Panzlaff Date: Sun, 1 Aug 2021 12:39:24 +0200 Subject: arm7: split SND into SND_global and SND_channel --- arm7/arm7.lsf | 3 +- arm7/lib/include/SND.h | 15 --- arm7/lib/include/SND_channel.h | 47 +++++++++ arm7/lib/include/SND_exChannel.h | 43 --------- arm7/lib/include/SND_global.h | 14 +++ arm7/lib/include/SND_main.h | 2 - arm7/lib/src/SND.c | 200 --------------------------------------- arm7/lib/src/SND_channel.c | 151 +++++++++++++++++++++++++++++ arm7/lib/src/SND_command.c | 3 +- arm7/lib/src/SND_exChannel.c | 5 +- arm7/lib/src/SND_global.c | 53 +++++++++++ arm7/lib/src/SND_main.c | 2 +- arm7/lib/src/SND_work.c | 1 + 13 files changed, 275 insertions(+), 264 deletions(-) delete mode 100644 arm7/lib/include/SND.h create mode 100644 arm7/lib/include/SND_channel.h create mode 100644 arm7/lib/include/SND_global.h delete mode 100644 arm7/lib/src/SND.c create mode 100644 arm7/lib/src/SND_channel.c create mode 100644 arm7/lib/src/SND_global.c diff --git a/arm7/arm7.lsf b/arm7/arm7.lsf index c8c7e318..950f30e7 100644 --- a/arm7/arm7.lsf +++ b/arm7/arm7.lsf @@ -40,7 +40,8 @@ Autoload WRAM Object PXI_fifo.o Object EXI_genPort.o Object PAD_xyButton.o - Object SND.o + Object SND_global.o + Object SND_channel.o Object SND_util.o Object SND_main.o Object SND_capture.o diff --git a/arm7/lib/include/SND.h b/arm7/lib/include/SND.h deleted file mode 100644 index 196377ed..00000000 --- a/arm7/lib/include/SND.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef GUARD_SND_H -#define GUARD_SND_H - -#include "nitro/types.h" - -void SND_Enable(void); -void SND_Disable(void); -void SND_Shutdown(void); -void SND_BeginSleep(void); -void SND_EndSleep(void); -void SND_SetMasterPan(int pan); -void SND_SetMasterVolume(int vol); -void SND_SetOutputSelector(int leftOutputFrom, int rightOutputFrom, int outputCh1ToMixer, int outputCh3ToMixer); - -#endif //GUARD_SND_H diff --git a/arm7/lib/include/SND_channel.h b/arm7/lib/include/SND_channel.h new file mode 100644 index 00000000..0c3cbe7b --- /dev/null +++ b/arm7/lib/include/SND_channel.h @@ -0,0 +1,47 @@ +#ifndef GUARD_SND_CHANNEL_H +#define GUARD_SND_CHANNEL_H + +#include "nitro/types.h" + +void SND_SetupChannelPcm( + int chnIdx, + const void *data, + int format, + int loop, + int loopStart, + int loopLen, + int volume, + int volumeDiv, + int timer, + int pan +); + +void SND_SetupChannelPsg( + int chnIdx, + int waveDuty, + int volume, + int volumeDiv, + int timer, + int pan +); + +void SND_SetupChannelNoise( + int chnIdx, + int volume, + int volumeDiv, + int timer, + int pan +); + +void SND_StopChannel(int chnIdx, int hold); + +void SND_SetChannelVolume(int chnIdx, int volume, int volumeDiv); +void SND_SetChannelTimer(int chnIdx, int timer); +void SND_SetChannelPan(int chnIdx, int pan); + +BOOL SND_IsChannelActive(int idx); +void SND_SetMasterPan(int pan); +u32 SND_GetChannelControl(int idx); +void SNDi_SetSurroundDecay(int decay); + +#endif //GUARD_SND_CHANNEL_H diff --git a/arm7/lib/include/SND_exChannel.h b/arm7/lib/include/SND_exChannel.h index a2d19971..99f8de21 100644 --- a/arm7/lib/include/SND_exChannel.h +++ b/arm7/lib/include/SND_exChannel.h @@ -21,7 +21,6 @@ void SND_ReleaseExChannel(struct SNDExChannel *chn); BOOL SND_IsExChannelActive(struct SNDExChannel *chn); struct SNDExChannel *SND_AllocExChannel(u32 channelMask, int priority, u32 flags, SNDExChannelCallback callback, void *callbackUserData); void SND_FreeExChannel(struct SNDExChannel *chn); -BOOL SND_IsChannelActive(int idx); void SND_InvalidateWave(const void *start, const void *end); // TODO internal functions, move these so exChannel @@ -42,47 +41,5 @@ void SND_InitLfoParam(struct SNDLfoParam *lfoParam); void SND_StartLfo(struct SNDLfo *lfo); void SND_UpdateLfo(struct SNDLfo *lfo); int SND_GetLfoValue(struct SNDLfo *lfo); -void SNDi_SetSurroundDecay(int decay); - -void SND_SetupChannelPcm( - int chnIdx, - const void *data, - int format, - int loop, - int loopStart, - int loopLen, - int volume, - int volumeDiv, - int timer, - int pan -); - -void SND_SetupChannelPsg( - int chnIdx, - int waveDuty, - int volume, - int volumeDiv, - int timer, - int pan -); - -void SND_SetupChannelNoise( - int chnIdx, - int volume, - int volumeDiv, - int timer, - int pan -); - -void SND_StopChannel(int chnIdx, int hold); - -void SND_SetChannelVolume(int chnIdx, int volume, int volumeDiv); -void SND_SetChannelPan(int chnIdx, int pan); -void SND_SetChannelTimer(int chnIdx, int timer); - -u32 SND_GetChannelControl(int idx); - -// TODO move this function to SND_exChannel.c -u16 CalcDecayCoeff(int value); #endif //GUARD_SND_EXCHANNEL_H diff --git a/arm7/lib/include/SND_global.h b/arm7/lib/include/SND_global.h new file mode 100644 index 00000000..47bb7a69 --- /dev/null +++ b/arm7/lib/include/SND_global.h @@ -0,0 +1,14 @@ +#ifndef GUARD_SND_GLOBAL_H +#define GUARD_SND_GLOBAL_H + +#include "nitro/types.h" + +void SND_Enable(void); +void SND_Disable(void); +void SND_Shutdown(void); +void SND_BeginSleep(void); +void SND_EndSleep(void); +void SND_SetMasterVolume(int vol); +void SND_SetOutputSelector(int leftOutputFrom, int rightOutputFrom, int outputCh1ToMixer, int outputCh3ToMixer); + +#endif //GUARD_SND_GLOBAL_H diff --git a/arm7/lib/include/SND_main.h b/arm7/lib/include/SND_main.h index fc72ae33..eba3ff44 100644 --- a/arm7/lib/include/SND_main.h +++ b/arm7/lib/include/SND_main.h @@ -12,7 +12,5 @@ u32 SND_WaitForIntervalTimer(void); void SND_SendWakeupMessage(void); void SNDi_LockMutex(void); void SNDi_UnlockMutex(void); -void SND_SetMasterVolume(int vol); -void SND_SetMasterPan(int pan); #endif //GUARD_SND_MAIN_H diff --git a/arm7/lib/src/SND.c b/arm7/lib/src/SND.c deleted file mode 100644 index c4b9d900..00000000 --- a/arm7/lib/src/SND.c +++ /dev/null @@ -1,200 +0,0 @@ -#include "SND.h" - -#include "registers.h" -#include "syscall.h" - -#include "OS_system.h" -#include "PM.h" -#include "SND_exChannel.h" -#include "SND_work.h" - -static int sMasterPan = -1; - -static u8 sOrgVolume[SND_CHANNEL_COUNT]; -static u8 sOrgPan[SND_CHANNEL_COUNT]; -static int sSurroundDecay; - -static int CalcSurroundDecay(int vol, int pan); - -void SND_SetupChannelPcm(int chnIdx, const void *data, int format, int loop, int loopStart, int loopLength, int volume, int volumeDiv, int timer, int pan) { - int off = chnIdx * 0x10; - - sOrgPan[chnIdx] = (u8)pan; - if (sMasterPan >= 0) - pan = sMasterPan; - - sOrgVolume[chnIdx] = (u8)volume; - if (sSurroundDecay > 0 && (1 << chnIdx) & 0xFFF5) { - volume = CalcSurroundDecay(volume, pan); - } - - reg_SOUNDoffCNT(off) = (u32)((format << 29) | (loop << 27) | (pan << 16) | (volumeDiv << 8) | (volume)); - reg_SOUNDoffTMR(off) = (u16)(0x10000 - timer); - reg_SOUNDoffPNT(off) = (u16)loopStart; - reg_SOUNDoffLEN(off) = (u32)loopLength; - reg_SOUNDoffSAD(off) = (u32)data; -} - -void SND_SetupChannelPsg(int chnIdx, int duty, int volume, int volumeDiv, int timer, int pan) { - int off = chnIdx * 0x10; - - sOrgPan[chnIdx] = (u8)pan; - if (sMasterPan >= 0) - pan = sMasterPan; - - sOrgVolume[chnIdx] = (u8)volume; - if (sSurroundDecay > 0 && (1 << chnIdx) & 0xFFF5) { - volume = CalcSurroundDecay(volume, pan); - } - - reg_SOUNDoffCNT(off) = (u32)(0x60000000 | (duty << 24) | (pan << 16) | (volumeDiv << 8) | volume); - reg_SOUNDoffTMR(off) = (u16)(0x10000 - timer); -} - -void SND_SetupChannelNoise(int chnIdx, int volume, int volumeDiv, int timer, int pan) { - int off = chnIdx * 0x10; - - sOrgPan[chnIdx] = (u8)pan; - if (sMasterPan >= 0) - pan = sMasterPan; - - sOrgVolume[chnIdx] = (u8)volume; - if (sSurroundDecay > 0 && (1 << chnIdx) & 0xFFF5) { - volume = CalcSurroundDecay(volume, pan); - } - - reg_SOUNDoffCNT(off) = (u32)(0x60000000 | (pan << 16) | (volumeDiv << 8) | volume); - reg_SOUNDoffTMR(off) = (u16)(0x10000 - timer); -} - -void SND_StopChannel(int idx, int hold) { - vu32 *reg = ®_SOUNDxCNT(idx); - - u32 v = *reg; - - // disable channel - v &= ~0x80000000; - - // set hold flag - if (hold & 1) - v |= 0x8000; - - *reg = v; -} - -void SND_SetChannelVolume(int chnIdx, int vol, int volDiv) { - sOrgVolume[chnIdx] = (u8)vol; - - if (sSurroundDecay > 0 && (1 << chnIdx) & 0xFFF5) { - int pan = reg_SOUNDxCNT_PAN(chnIdx); - vol = CalcSurroundDecay(vol, pan); - } - - reg_SOUNDxCNT_VOLS(chnIdx) = (u16)((volDiv << 8) | vol); -} - -void SND_SetChannelTimer(int chnIdx, int timer) { - reg_SOUNDxTMR(chnIdx) = (u16)(0x10000 - timer); -} - -void SND_SetChannelPan(int chnIdx, int pan) { - sOrgPan[chnIdx] = (u8)pan; - - if (sMasterPan >= 0) { - pan = sMasterPan; - } - - reg_SOUNDxCNT_PAN(chnIdx) = (u8)pan; - - if (sSurroundDecay > 0 && (1 << chnIdx) & 0xFFF5) { - reg_SOUNDxCNT_VOL(chnIdx) = (u8)CalcSurroundDecay(sOrgVolume[chnIdx], pan); - } -} - -BOOL SND_IsChannelActive(int chnIdx) { - return (reg_SOUNDxCNT_STAT(chnIdx) & 0x80) != 0; -} - -void SND_SetMasterPan(int pan) { - sMasterPan = pan; - - if (pan >= 0) { - for (int i = 0; i < SND_CHANNEL_COUNT; i++) { - reg_SOUNDxCNT_PAN(i) = (u8)pan; - } - } else { - for (int i = 0; i < SND_CHANNEL_COUNT; i++) { - reg_SOUNDxCNT_PAN(i) = sOrgPan[i]; - } - } -} - -u32 SND_GetChannelControl(int chnIdx) { - return reg_SOUNDxCNT(chnIdx); -} - -void SNDi_SetSurroundDecay(int decay) { - sSurroundDecay = decay; - - for (int i = 0; i < SND_CHANNEL_COUNT; i++) { - // do not process channel 1+3 (capture playback channels) - if ((1 << i) & 0xFFF5) { - int pan = reg_SOUNDxCNT_PAN(i); - reg_SOUNDxCNT_VOL(i) = (u8)CalcSurroundDecay(sOrgVolume[i], pan); - } - } -} - -static int CalcSurroundDecay(int vol, int pan) { - if (pan < 24) { - return vol * (sSurroundDecay * (pan + 40) + ((0x7FFF - sSurroundDecay) << 6)) >> 21; - } else if (pan <= 104) { - return vol; - } else { - return vol * (-sSurroundDecay * (pan - 40) + ((sSurroundDecay + 0x7FFF) << 6)) >> 21; - } -} - -void SND_Enable(void) { - reg_SOUNDCNT_MIX |= 0x80; -} - -void SND_Disable(void) { - reg_SOUNDCNT_MIX &= ~0x80; -} - -void SND_Shutdown(void) { - SND_Disable(); - - for (int i = 0; i < SND_CHANNEL_COUNT; i++) { - SND_StopChannel(i, 1); - } - - reg_SNDCAPxCNT(0) = 0; - reg_SNDCAPxCNT(1) = 0; -} - -void SND_BeginSleep(void) { - SND_Disable(); - SVC_SoundBiasReset(0x80); - OS_SpinWait(0x40000); - PMi_ResetControl(1); - reg_POWCNT2 &= ~1; -} - -void SND_EndSleep(void) { - reg_POWCNT2 |= 1; // enable speakers - PMi_SetControl(1); - SVC_SoundBiasSet(0x100); - OS_SpinWait(0x7AB80); // what does this wait for and how long does it wait? - SND_Enable(); -} - -void SND_SetMasterVolume(int vol) { - reg_SOUNDCNT_VOL = (u8)vol; -} - -void SND_SetOutputSelector(int leftOutputFrom, int rightOutputFrom, int outputCh1ToMixer, int outputCh3ToMixer) { - int masterEnable = (reg_SOUNDCNT_MIX & 0x80) ? 1 : 0; - reg_SOUNDCNT_MIX = (u8)((masterEnable << 7) | (outputCh3ToMixer << 5) | (outputCh1ToMixer << 4) | (rightOutputFrom << 2) | (leftOutputFrom)); -} diff --git a/arm7/lib/src/SND_channel.c b/arm7/lib/src/SND_channel.c new file mode 100644 index 00000000..99b80a7c --- /dev/null +++ b/arm7/lib/src/SND_channel.c @@ -0,0 +1,151 @@ +#include "SND_channel.h" + +#include "registers.h" +#include "SND_work.h" + +static int sMasterPan = -1; + +static u8 sOrgVolume[SND_CHANNEL_COUNT]; +static u8 sOrgPan[SND_CHANNEL_COUNT]; +static int sSurroundDecay; + +static int CalcSurroundDecay(int vol, int pan); + +void SND_SetupChannelPcm(int chnIdx, const void *data, int format, int loop, int loopStart, int loopLength, int volume, int volumeDiv, int timer, int pan) { + int off = chnIdx * 0x10; + + sOrgPan[chnIdx] = (u8)pan; + if (sMasterPan >= 0) + pan = sMasterPan; + + sOrgVolume[chnIdx] = (u8)volume; + if (sSurroundDecay > 0 && (1 << chnIdx) & 0xFFF5) { + volume = CalcSurroundDecay(volume, pan); + } + + reg_SOUNDoffCNT(off) = (u32)((format << 29) | (loop << 27) | (pan << 16) | (volumeDiv << 8) | (volume)); + reg_SOUNDoffTMR(off) = (u16)(0x10000 - timer); + reg_SOUNDoffPNT(off) = (u16)loopStart; + reg_SOUNDoffLEN(off) = (u32)loopLength; + reg_SOUNDoffSAD(off) = (u32)data; +} + +void SND_SetupChannelPsg(int chnIdx, int duty, int volume, int volumeDiv, int timer, int pan) { + int off = chnIdx * 0x10; + + sOrgPan[chnIdx] = (u8)pan; + if (sMasterPan >= 0) + pan = sMasterPan; + + sOrgVolume[chnIdx] = (u8)volume; + if (sSurroundDecay > 0 && (1 << chnIdx) & 0xFFF5) { + volume = CalcSurroundDecay(volume, pan); + } + + reg_SOUNDoffCNT(off) = (u32)(0x60000000 | (duty << 24) | (pan << 16) | (volumeDiv << 8) | volume); + reg_SOUNDoffTMR(off) = (u16)(0x10000 - timer); +} + +void SND_SetupChannelNoise(int chnIdx, int volume, int volumeDiv, int timer, int pan) { + int off = chnIdx * 0x10; + + sOrgPan[chnIdx] = (u8)pan; + if (sMasterPan >= 0) + pan = sMasterPan; + + sOrgVolume[chnIdx] = (u8)volume; + if (sSurroundDecay > 0 && (1 << chnIdx) & 0xFFF5) { + volume = CalcSurroundDecay(volume, pan); + } + + reg_SOUNDoffCNT(off) = (u32)(0x60000000 | (pan << 16) | (volumeDiv << 8) | volume); + reg_SOUNDoffTMR(off) = (u16)(0x10000 - timer); +} + +void SND_StopChannel(int idx, int hold) { + vu32 *reg = ®_SOUNDxCNT(idx); + + u32 v = *reg; + + // disable channel + v &= ~0x80000000; + + // set hold flag + if (hold & 1) + v |= 0x8000; + + *reg = v; +} + +void SND_SetChannelVolume(int chnIdx, int vol, int volDiv) { + sOrgVolume[chnIdx] = (u8)vol; + + if (sSurroundDecay > 0 && (1 << chnIdx) & 0xFFF5) { + int pan = reg_SOUNDxCNT_PAN(chnIdx); + vol = CalcSurroundDecay(vol, pan); + } + + reg_SOUNDxCNT_VOLS(chnIdx) = (u16)((volDiv << 8) | vol); +} + +void SND_SetChannelTimer(int chnIdx, int timer) { + reg_SOUNDxTMR(chnIdx) = (u16)(0x10000 - timer); +} + +void SND_SetChannelPan(int chnIdx, int pan) { + sOrgPan[chnIdx] = (u8)pan; + + if (sMasterPan >= 0) { + pan = sMasterPan; + } + + reg_SOUNDxCNT_PAN(chnIdx) = (u8)pan; + + if (sSurroundDecay > 0 && (1 << chnIdx) & 0xFFF5) { + reg_SOUNDxCNT_VOL(chnIdx) = (u8)CalcSurroundDecay(sOrgVolume[chnIdx], pan); + } +} + +BOOL SND_IsChannelActive(int chnIdx) { + return (reg_SOUNDxCNT_STAT(chnIdx) & 0x80) != 0; +} + +void SND_SetMasterPan(int pan) { + sMasterPan = pan; + + if (pan >= 0) { + for (int i = 0; i < SND_CHANNEL_COUNT; i++) { + reg_SOUNDxCNT_PAN(i) = (u8)pan; + } + } else { + for (int i = 0; i < SND_CHANNEL_COUNT; i++) { + reg_SOUNDxCNT_PAN(i) = sOrgPan[i]; + } + } +} + +u32 SND_GetChannelControl(int chnIdx) { + return reg_SOUNDxCNT(chnIdx); +} + +void SNDi_SetSurroundDecay(int decay) { + sSurroundDecay = decay; + + for (int i = 0; i < SND_CHANNEL_COUNT; i++) { + // do not process channel 1+3 (capture playback channels) + if ((1 << i) & 0xFFF5) { + int pan = reg_SOUNDxCNT_PAN(i); + reg_SOUNDxCNT_VOL(i) = (u8)CalcSurroundDecay(sOrgVolume[i], pan); + } + } +} + +static int CalcSurroundDecay(int vol, int pan) { + if (pan < 24) { + return vol * (sSurroundDecay * (pan + 40) + ((0x7FFF - sSurroundDecay) << 6)) >> 21; + } else if (pan <= 104) { + return vol; + } else { + return vol * (-sSurroundDecay * (pan - 40) + ((sSurroundDecay + 0x7FFF) << 6)) >> 21; + } +} diff --git a/arm7/lib/src/SND_command.c b/arm7/lib/src/SND_command.c index ada6161c..bcb43d73 100644 --- a/arm7/lib/src/SND_command.c +++ b/arm7/lib/src/SND_command.c @@ -7,10 +7,11 @@ #include "PXI_fifo.h" #include "OS_message.h" #include "OS_system.h" -#include "SND.h" +#include "SND_channel.h" #include "SND_alarm.h" #include "SND_capture.h" #include "SND_exChannel.h" +#include "SND_global.h" #include "SND_main.h" #include "SND_seq.h" #include "SND_work.h" diff --git a/arm7/lib/src/SND_exChannel.c b/arm7/lib/src/SND_exChannel.c index 7e41aea3..01bd4f3e 100644 --- a/arm7/lib/src/SND_exChannel.c +++ b/arm7/lib/src/SND_exChannel.c @@ -1,5 +1,6 @@ #include "SND_exChannel.h" +#include "SND_channel.h" #include "SND_main.h" #include "SND_work.h" #include "SND_util.h" @@ -16,6 +17,8 @@ static u32 sWeakLockedChannelMask; // TODO remove this extern once we actually know where this table is extern u8 sSampleDataShiftTable[4]; +static u16 CalcDecayCoeff(int vol); + void SND_ExChannelInit(void) { struct SNDExChannel *chn; s32 i; @@ -471,7 +474,7 @@ int SND_GetLfoValue(struct SNDLfo *lfo) { } } -u16 CalcDecayCoeff(int vol) { +static u16 CalcDecayCoeff(int vol) { if (vol == 127) return 0xFFFF; else if (vol == 126) diff --git a/arm7/lib/src/SND_global.c b/arm7/lib/src/SND_global.c new file mode 100644 index 00000000..0654934f --- /dev/null +++ b/arm7/lib/src/SND_global.c @@ -0,0 +1,53 @@ +#include "SND_global.h" + +#include "SND_channel.h" +#include "SND_work.h" + +#include "OS_system.h" +#include "PM.h" +#include "registers.h" +#include "syscall.h" + +void SND_Enable(void) { + reg_SOUNDCNT_MIX |= 0x80; +} + +void SND_Disable(void) { + reg_SOUNDCNT_MIX &= ~0x80; +} + +void SND_Shutdown(void) { + SND_Disable(); + + for (int i = 0; i < SND_CHANNEL_COUNT; i++) { + SND_StopChannel(i, 1); + } + + reg_SNDCAPxCNT(0) = 0; + reg_SNDCAPxCNT(1) = 0; +} + +void SND_BeginSleep(void) { + SND_Disable(); + SVC_SoundBiasReset(0x80); + OS_SpinWait(0x40000); + PMi_ResetControl(1); + reg_POWCNT2 &= ~1; +} + +void SND_EndSleep(void) { + reg_POWCNT2 |= 1; // enable speakers + PMi_SetControl(1); + SVC_SoundBiasSet(0x100); + OS_SpinWait(0x7AB80); // what does this wait for and how long does it wait? + SND_Enable(); +} + +void SND_SetMasterVolume(int vol) { + reg_SOUNDCNT_VOL = (u8)vol; +} + +void SND_SetOutputSelector(int leftOutputFrom, int rightOutputFrom, int outputCh1ToMixer, int outputCh3ToMixer) { + int masterEnable = (reg_SOUNDCNT_MIX & 0x80) ? 1 : 0; + reg_SOUNDCNT_MIX = (u8)((masterEnable << 7) | (outputCh3ToMixer << 5) | (outputCh1ToMixer << 4) | (rightOutputFrom << 2) | (leftOutputFrom)); +} diff --git a/arm7/lib/src/SND_main.c b/arm7/lib/src/SND_main.c index 96dcdc78..24e81d2c 100644 --- a/arm7/lib/src/SND_main.c +++ b/arm7/lib/src/SND_main.c @@ -2,11 +2,11 @@ #include "global.h" -#include "SND.h" #include "SND_alarm.h" #include "SND_capture.h" #include "SND_command.h" #include "SND_exChannel.h" +#include "SND_global.h" #include "SND_seq.h" #include "SND_util.h" #include "SND_work.h" diff --git a/arm7/lib/src/SND_work.c b/arm7/lib/src/SND_work.c index 3f0d10f0..d40ccdc6 100644 --- a/arm7/lib/src/SND_work.c +++ b/arm7/lib/src/SND_work.c @@ -1,5 +1,6 @@ #include "SND_work.h" +#include "SND_channel.h" #include "SND_exChannel.h" #include "SND_capture.h" -- cgit v1.2.3