Sound system refactor

This commit is contained in:
elasota
2019-12-31 04:49:38 -05:00
parent b963aa9b5f
commit 62438ab4f3
7 changed files with 287 additions and 375 deletions

View File

@@ -14,6 +14,7 @@
#include "SoundSync.h"
#include "HostMutex.h"
#include "HostSystemServices.h"
#include "MemoryManager.h"
#define kBaseBufferMusicID 2000
@@ -22,15 +23,14 @@
#define kLastGamePiece 6
void MusicCallBack (SndChannelPtr, SndCommand *);
void MusicCallBack (PortabilityLayer::AudioChannel *channel);
PLError_t LoadMusicSounds (void);
PLError_t DumpMusicSounds (void);
PLError_t OpenMusicChannel (void);
PLError_t CloseMusicChannel (void);
SndCallBackUPP musicCallBackUPP;
SndChannelPtr musicChannel;
PortabilityLayer::AudioChannel *musicChannel;
Ptr theMusicData[kMaxMusic];
short musicScore[kLastMusicPiece];
short gameScore[kLastGamePiece];
@@ -56,7 +56,6 @@ extern Boolean isSoundOn;
PLError_t StartMusic (void)
{
SndCommand theCommand;
PLError_t theErr;
short soundVolume;
@@ -72,37 +71,16 @@ PLError_t StartMusic (void)
if ((soundVolume != 0) && (!failedMusic))
{
theCommand.cmd = bufferCmd;
theCommand.param1 = 0;
theCommand.param2 = (intptr_t)(theMusicData[musicState.musicSoundID]);
theErr = SndDoCommand(musicChannel, &theCommand, false);
if (theErr != PLErrors::kNone)
return (theErr);
// GP: No idea what "1964" means
theCommand.cmd = nullCmd;
theCommand.param1 = 1964;
theCommand.param2 = 0;
theErr = SndDoCommand(musicChannel, &theCommand, false);
if (theErr != PLErrors::kNone)
return (theErr);
musicChannel->AddBuffer(theMusicData[musicState.musicSoundID], true);
// Don't need to lock here because the callback should not trigger until queued
musicState.musicCursor++;
if (musicState.musicCursor >= kLastMusicPiece)
musicState.musicCursor = 0;
musicState.musicSoundID = musicScore[musicState.musicCursor];
theCommand.cmd = bufferCmd;
theCommand.param1 = 0;
theCommand.param2 = (intptr_t)(theMusicData[musicState.musicSoundID]);
theErr = SndDoCommand(musicChannel, &theCommand, false);
if (theErr != PLErrors::kNone)
return (theErr);
theCommand.cmd = callBackCmd;
theCommand.param1 = 0;
theCommand.param2 = 0;
theErr = SndDoCommand(musicChannel, &theCommand, false);
musicChannel->AddBuffer(theMusicData[musicState.musicSoundID], true);
musicChannel->AddCallback(MusicCallBack, true);
isMusicOn = true;
}
@@ -114,7 +92,6 @@ PLError_t StartMusic (void)
void StopTheMusic (void)
{
SndCommand theCommand;
PLError_t theErr;
if (dontLoadMusic)
@@ -123,15 +100,8 @@ void StopTheMusic (void)
theErr = PLErrors::kNone;
if ((isMusicOn) && (!failedMusic))
{
theCommand.cmd = flushCmd;
theCommand.param1 = 0;
theCommand.param2 = 0L;
theErr = SndDoImmediate(musicChannel, &theCommand);
theCommand.cmd = quietCmd;
theCommand.param1 = 0;
theCommand.param2 = 0L;
theErr = SndDoImmediate(musicChannel, &theCommand);
musicChannel->ClearAllCommands();
musicChannel->Stop();
isMusicOn = false;
}
@@ -186,12 +156,9 @@ void SetMusicalMode (short newMode)
//-------------------------------------------------------------- MusicCallBack
void MusicCallBack (SndChannelPtr theChannel, SndCommand *theCommand)
void MusicCallBack (PortabilityLayer::AudioChannel *theChannel)
{
PLError_t theErr;
// gameA5 = theCommand.param2;
// thisA5 = SetA5(gameA5);
musicMutex->Lock();
switch (musicState.musicMode)
@@ -222,16 +189,9 @@ void MusicCallBack (SndChannelPtr theChannel, SndCommand *theCommand)
short musicSoundID = musicState.musicSoundID;
musicMutex->Unlock();
theCommand->cmd = bufferCmd;
theCommand->param1 = 0;
theCommand->param2 = (intptr_t)(theMusicData[musicSoundID]);
theErr = SndDoCommand(musicChannel, theCommand, false);
theCommand->cmd = callBackCmd;
theCommand->param1 = 0;
theCommand->param2 = 0;
theErr = SndDoCommand(musicChannel, theCommand, false);
theChannel->AddBuffer(theMusicData[musicSoundID], true);
theChannel->AddCallback(MusicCallBack, true);
}
//-------------------------------------------------------------- LoadMusicSounds
@@ -256,7 +216,7 @@ PLError_t LoadMusicSounds (void)
soundDataSize = GetHandleSize(theSound) - 20L;
theMusicData[i] = NewPtr(soundDataSize);
theMusicData[i] = PortabilityLayer::MemoryManager::GetInstance()->Alloc(soundDataSize);
if (theMusicData[i] == nil)
return PLErrors::kOutOfMemory;
@@ -278,7 +238,7 @@ PLError_t DumpMusicSounds (void)
for (i = 0; i < kMaxMusic; i++)
{
if (theMusicData[i] != nil)
DisposePtr(theMusicData[i]);
PortabilityLayer::MemoryManager::GetInstance()->Release(theMusicData[i]);
theMusicData[i] = nil;
}
@@ -291,18 +251,16 @@ PLError_t OpenMusicChannel (void)
{
PLError_t theErr;
musicCallBackUPP = NewSndCallBackProc(MusicCallBack);
theErr = PLErrors::kNone;
if (musicChannel != nil)
return (theErr);
musicChannel = nil;
theErr = SndNewChannel(&musicChannel,
sampledSynth, initNoInterp + initMono,
(SndCallBackUPP)musicCallBackUPP);
musicChannel = PortabilityLayer::SoundSystem::GetInstance()->CreateChannel();
if (musicChannel == nil)
theErr = PLErrors::kAudioError;
return (theErr);
}
@@ -315,11 +273,9 @@ PLError_t CloseMusicChannel (void)
theErr = PLErrors::kNone;
if (musicChannel != nil)
theErr = SndDisposeChannel(musicChannel, true);
musicChannel->Destroy(false);
musicChannel = nil;
DisposeSndCallBackUPP(musicCallBackUPP);
return (theErr);
}

View File

@@ -9,6 +9,7 @@
#include "PLResources.h"
#include "PLSound.h"
#include "Externs.h"
#include "MemoryManager.h"
#include "SoundSync.h"
#include "VirtualDirectory.h"
@@ -17,17 +18,16 @@
#define kMaxSounds 64
void CallBack0 (SndChannelPtr, SndCommand *);
void CallBack1 (SndChannelPtr, SndCommand *);
void CallBack2 (SndChannelPtr, SndCommand *);
void CallBack0 (PortabilityLayer::AudioChannel *);
void CallBack1 (PortabilityLayer::AudioChannel *);
void CallBack2 (PortabilityLayer::AudioChannel *);
PLError_t LoadBufferSounds (void);
void DumpBufferSounds (void);
PLError_t OpenSoundChannels (void);
PLError_t CloseSoundChannels (void);
void CloseSoundChannels (void);
SndCallBackUPP callBack0UPP, callBack1UPP, callBack2UPP;
SndChannelPtr channel0, channel1, channel2;
PortabilityLayer::AudioChannel *channel0, *channel1, *channel2;
Ptr theSoundData[kMaxSounds];
short numSoundsLoaded;
Boolean soundLoaded[kMaxSounds], dontLoadSounds;
@@ -76,131 +76,97 @@ void PlayPrioritySound (short which, short priority)
void FlushAnyTriggerPlaying (void)
{
SndCommand theCommand;
PLError_t theErr;
SoundSyncState ss = SoundSync_ReadAll();
if (ss.priority0 == kTriggerPriority)
{
theCommand.cmd = quietCmd;
theCommand.param1 = 0;
theCommand.param2 = 0;
theErr = SndDoImmediate(channel0, &theCommand);
theCommand.cmd = flushCmd;
theCommand.param1 = 0;
theCommand.param2 = 0;
theErr = SndDoImmediate(channel0, &theCommand);
channel0->ClearAllCommands();
channel0->Stop();
}
if (ss.priority1 == kTriggerPriority)
{
theCommand.cmd = quietCmd;
theCommand.param1 = 0;
theCommand.param2 = 0;
theErr = SndDoImmediate(channel1, &theCommand);
theCommand.cmd = flushCmd;
theCommand.param1 = 0;
theCommand.param2 = 0;
theErr = SndDoImmediate(channel1, &theCommand);
channel1->ClearAllCommands();
channel1->Stop();
}
if (ss.priority2 == kTriggerPriority)
{
theCommand.cmd = quietCmd;
theCommand.param1 = 0;
theCommand.param2 = 0;
theErr = SndDoImmediate(channel2, &theCommand);
theCommand.cmd = flushCmd;
theCommand.param1 = 0;
theCommand.param2 = 0;
theErr = SndDoImmediate(channel2, &theCommand);
}
}
//-------------------------------------------------------------- PlaySound0
void PlayExclusiveSoundChannel(short channelIndex, short soundID, short oldPriority, short newPriority)
{
SndCommand theCommand;
PLError_t theErr;
if (failedSound || dontLoadSounds)
return;
SndChannelPtr channel = nil;
switch (channelIndex)
{
case 0:
channel = channel0;
break;
case 1:
channel = channel2;
break;
case 2:
channel = channel2;
break;
default:
return;
}
theErr = PLErrors::kNone;
if (isSoundOn)
{
if (oldPriority != 0)
{
// Flush the queue and stop the channel, which will remove the pending callback
theCommand.cmd = flushCmd;
theCommand.param1 = 0;
theCommand.param2 = 0;
theErr = SndDoImmediate(channel, &theCommand);
theCommand.cmd = quietCmd;
theCommand.param1 = 0;
theCommand.param2 = 0;
theErr = SndDoImmediate(channel, &theCommand);
SoundSync_ClearPriority(channelIndex);
}
SoundSync_PutPriority(channelIndex, newPriority);
theCommand.cmd = bufferCmd;
theCommand.param1 = 0;
theCommand.param2 = (intptr_t)(theSoundData[soundID]);
theErr = SndDoCommand(channel, &theCommand, true);
theCommand.cmd = callBackCmd;
theCommand.param1 = 0;
theCommand.param2 = 0;
theErr = SndDoCommand(channel, &theCommand, true);
if (theErr != PLErrors::kNone)
SoundSync_ClearPriority(channelIndex);
channel2->ClearAllCommands();
channel2->Stop();
}
}
//-------------------------------------------------------------- CallBack0
void CallBack0 (SndChannelPtr theChannel, SndCommand *theCommand)
void CallBack0(PortabilityLayer::AudioChannel *theChannel)
{
SoundSync_ClearPriority(0);
}
//-------------------------------------------------------------- CallBack1
void CallBack1 (SndChannelPtr theChannel, SndCommand *theCommand)
void CallBack1(PortabilityLayer::AudioChannel *theChannel)
{
SoundSync_ClearPriority(1);
}
//-------------------------------------------------------------- CallBack2
void CallBack2 (SndChannelPtr theChannel, SndCommand *theCommand)
void CallBack2(PortabilityLayer::AudioChannel *theChannel)
{
SoundSync_ClearPriority(2);
}
//-------------------------------------------------------------- PlaySound0
void PlayExclusiveSoundChannel(short channelIndex, short soundID, short oldPriority, short newPriority)
{
if (failedSound || dontLoadSounds)
return;
PortabilityLayer::AudioChannel *channel = nil;
PortabilityLayer::AudioChannelCallback_t callback = nil;
switch (channelIndex)
{
case 0:
channel = channel0;
callback = CallBack0;
break;
case 1:
channel = channel1;
callback = CallBack1;
break;
case 2:
channel = channel2;
callback = CallBack2;
break;
default:
return;
}
if (isSoundOn)
{
if (oldPriority != 0)
{
// Flush the queue and stop the channel, which will remove the pending callback
channel->ClearAllCommands();
channel->Stop();
SoundSync_ClearPriority(channelIndex);
}
SoundSync_PutPriority(channelIndex, newPriority);
bool succeeded = channel->AddBuffer(theSoundData[soundID], false);
succeeded &= channel->AddCallback(callback, false);
if (!succeeded)
SoundSync_ClearPriority(channelIndex);
}
}
//-------------------------------------------------------------- LoadTriggerSound
PLError_t LoadTriggerSound (short soundID)
@@ -225,7 +191,7 @@ PLError_t LoadTriggerSound (short soundID)
else
{
soundDataSize = GetHandleSize(theSound) - 20L;
theSoundData[kMaxSounds - 1] = NewPtr(soundDataSize);
theSoundData[kMaxSounds - 1] = PortabilityLayer::MemoryManager::GetInstance()->Alloc(soundDataSize);
if (theSoundData[kMaxSounds - 1] == nil)
{
theSound.Dispose();
@@ -247,7 +213,7 @@ PLError_t LoadTriggerSound (short soundID)
void DumpTriggerSound (void)
{
if (theSoundData[kMaxSounds - 1] != nil)
DisposePtr(theSoundData[kMaxSounds - 1]);
PortabilityLayer::MemoryManager::GetInstance()->Release(theSoundData[kMaxSounds - 1]);
theSoundData[kMaxSounds - 1] = nil;
}
@@ -270,7 +236,7 @@ PLError_t LoadBufferSounds (void)
soundDataSize = GetHandleSize(theSound) - 20L;
theSoundData[i] = NewPtr(soundDataSize);
theSoundData[i] = PortabilityLayer::MemoryManager::GetInstance()->Alloc(soundDataSize);
if (theSoundData[i] == nil)
return (PLErrors::kOutOfMemory);
@@ -292,7 +258,7 @@ void DumpBufferSounds (void)
for (i = 0; i < kMaxSounds; i++)
{
if (theSoundData[i] != nil)
DisposePtr(theSoundData[i]);
PortabilityLayer::MemoryManager::GetInstance()->Release(theSoundData[i]);
theSoundData[i] = nil;
}
}
@@ -301,73 +267,50 @@ void DumpBufferSounds (void)
PLError_t OpenSoundChannels (void)
{
PLError_t theErr;
callBack0UPP = NewSndCallBackProc(CallBack0);
callBack1UPP = NewSndCallBackProc(CallBack1);
callBack2UPP = NewSndCallBackProc(CallBack2);
theErr = PLErrors::kNone;
if (channelOpen)
return (theErr);
return PLErrors::kAudioError;
theErr = SndNewChannel(&channel0,
sampledSynth, initNoInterp + initMono,
(SndCallBackUPP)callBack0UPP);
if (theErr == PLErrors::kNone)
channel0 = PortabilityLayer::SoundSystem::GetInstance()->CreateChannel();
if (channel0)
channelOpen = true;
else
return (theErr);
theErr = SndNewChannel(&channel1,
sampledSynth, initNoInterp + initMono,
(SndCallBackUPP)callBack1UPP);
if (theErr == PLErrors::kNone)
return PLErrors::kAudioError;
channel1 = PortabilityLayer::SoundSystem::GetInstance()->CreateChannel();
if (channel1)
channelOpen = true;
else
return (theErr);
theErr = SndNewChannel(&channel2,
sampledSynth, initNoInterp + initMono,
(SndCallBackUPP)callBack2UPP);
if (theErr == PLErrors::kNone)
return PLErrors::kAudioError;
channel2 = PortabilityLayer::SoundSystem::GetInstance()->CreateChannel();
if (channel2)
channelOpen = true;
else
return PLErrors::kAudioError;
return (theErr);
return PLErrors::kNone;
}
//-------------------------------------------------------------- CloseSoundChannels
PLError_t CloseSoundChannels (void)
void CloseSoundChannels (void)
{
PLError_t theErr;
theErr = PLErrors::kNone;
if (!channelOpen)
return (theErr);
return;
if (channel0 != nil)
theErr = SndDisposeChannel(channel0, true);
channel0->Destroy(false);
channel0 = nil;
if (channel1 != nil)
theErr = SndDisposeChannel(channel1, true);
channel1->Destroy(false);
channel1 = nil;
if (channel2 != nil)
theErr = SndDisposeChannel(channel2, true);
channel2->Destroy(false);
channel2 = nil;
if (theErr == PLErrors::kNone)
channelOpen = false;
DisposeSndCallBackUPP(callBack0UPP);
DisposeSndCallBackUPP(callBack1UPP);
DisposeSndCallBackUPP(callBack2UPP);
return (theErr);
channelOpen = false;
}
//-------------------------------------------------------------- InitSound
@@ -411,13 +354,11 @@ void InitSound (void)
void KillSound (void)
{
PLError_t theErr;
if (dontLoadSounds)
return;
DumpBufferSounds();
theErr = CloseSoundChannels();
CloseSoundChannels();
}
//-------------------------------------------------------------- SoundBytesNeeded

View File

@@ -511,8 +511,8 @@ void UnivGetSoundVolume (short *volume, Boolean hasSM3)
// if (hasSM3)
// {
theErr = GetDefaultOutputVolume(&longVol);
*volume = LoWord(longVol) / 0x0024;
longVol = PortabilityLayer::SoundSystem::GetInstance()->GetVolume();
*volume = longVol / 0x0024;
// }
// else
// GetSoundVol(volume);
@@ -530,7 +530,6 @@ void UnivGetSoundVolume (short *volume, Boolean hasSM3)
void UnivSetSoundVolume (short volume, Boolean hasSM3)
{
long longVol;
PLError_t theErr;
if (volume > 7)
volume = 7;
@@ -542,8 +541,8 @@ void UnivSetSoundVolume (short volume, Boolean hasSM3)
longVol = (long)volume * 0x0025;
if (longVol > 0x00000100)
longVol = 0x00000100;
longVol = longVol + (longVol << 16);
theErr = SetDefaultOutputVolume(longVol);
PortabilityLayer::SoundSystem::GetInstance()->SetVolume(longVol);
// }
// else
// SetSoundVol(volume);