mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-09-24 07:06:36 +00:00
Sound system refactor
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
#include "SoundSync.h"
|
#include "SoundSync.h"
|
||||||
#include "HostMutex.h"
|
#include "HostMutex.h"
|
||||||
#include "HostSystemServices.h"
|
#include "HostSystemServices.h"
|
||||||
|
#include "MemoryManager.h"
|
||||||
|
|
||||||
|
|
||||||
#define kBaseBufferMusicID 2000
|
#define kBaseBufferMusicID 2000
|
||||||
@@ -22,15 +23,14 @@
|
|||||||
#define kLastGamePiece 6
|
#define kLastGamePiece 6
|
||||||
|
|
||||||
|
|
||||||
void MusicCallBack (SndChannelPtr, SndCommand *);
|
void MusicCallBack (PortabilityLayer::AudioChannel *channel);
|
||||||
PLError_t LoadMusicSounds (void);
|
PLError_t LoadMusicSounds (void);
|
||||||
PLError_t DumpMusicSounds (void);
|
PLError_t DumpMusicSounds (void);
|
||||||
PLError_t OpenMusicChannel (void);
|
PLError_t OpenMusicChannel (void);
|
||||||
PLError_t CloseMusicChannel (void);
|
PLError_t CloseMusicChannel (void);
|
||||||
|
|
||||||
|
|
||||||
SndCallBackUPP musicCallBackUPP;
|
PortabilityLayer::AudioChannel *musicChannel;
|
||||||
SndChannelPtr musicChannel;
|
|
||||||
Ptr theMusicData[kMaxMusic];
|
Ptr theMusicData[kMaxMusic];
|
||||||
short musicScore[kLastMusicPiece];
|
short musicScore[kLastMusicPiece];
|
||||||
short gameScore[kLastGamePiece];
|
short gameScore[kLastGamePiece];
|
||||||
@@ -56,7 +56,6 @@ extern Boolean isSoundOn;
|
|||||||
|
|
||||||
PLError_t StartMusic (void)
|
PLError_t StartMusic (void)
|
||||||
{
|
{
|
||||||
SndCommand theCommand;
|
|
||||||
PLError_t theErr;
|
PLError_t theErr;
|
||||||
short soundVolume;
|
short soundVolume;
|
||||||
|
|
||||||
@@ -72,37 +71,16 @@ PLError_t StartMusic (void)
|
|||||||
|
|
||||||
if ((soundVolume != 0) && (!failedMusic))
|
if ((soundVolume != 0) && (!failedMusic))
|
||||||
{
|
{
|
||||||
theCommand.cmd = bufferCmd;
|
musicChannel->AddBuffer(theMusicData[musicState.musicSoundID], true);
|
||||||
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);
|
|
||||||
|
|
||||||
|
// Don't need to lock here because the callback should not trigger until queued
|
||||||
musicState.musicCursor++;
|
musicState.musicCursor++;
|
||||||
if (musicState.musicCursor >= kLastMusicPiece)
|
if (musicState.musicCursor >= kLastMusicPiece)
|
||||||
musicState.musicCursor = 0;
|
musicState.musicCursor = 0;
|
||||||
musicState.musicSoundID = musicScore[musicState.musicCursor];
|
musicState.musicSoundID = musicScore[musicState.musicCursor];
|
||||||
|
|
||||||
theCommand.cmd = bufferCmd;
|
musicChannel->AddBuffer(theMusicData[musicState.musicSoundID], true);
|
||||||
theCommand.param1 = 0;
|
musicChannel->AddCallback(MusicCallBack, true);
|
||||||
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);
|
|
||||||
|
|
||||||
isMusicOn = true;
|
isMusicOn = true;
|
||||||
}
|
}
|
||||||
@@ -114,7 +92,6 @@ PLError_t StartMusic (void)
|
|||||||
|
|
||||||
void StopTheMusic (void)
|
void StopTheMusic (void)
|
||||||
{
|
{
|
||||||
SndCommand theCommand;
|
|
||||||
PLError_t theErr;
|
PLError_t theErr;
|
||||||
|
|
||||||
if (dontLoadMusic)
|
if (dontLoadMusic)
|
||||||
@@ -123,15 +100,8 @@ void StopTheMusic (void)
|
|||||||
theErr = PLErrors::kNone;
|
theErr = PLErrors::kNone;
|
||||||
if ((isMusicOn) && (!failedMusic))
|
if ((isMusicOn) && (!failedMusic))
|
||||||
{
|
{
|
||||||
theCommand.cmd = flushCmd;
|
musicChannel->ClearAllCommands();
|
||||||
theCommand.param1 = 0;
|
musicChannel->Stop();
|
||||||
theCommand.param2 = 0L;
|
|
||||||
theErr = SndDoImmediate(musicChannel, &theCommand);
|
|
||||||
|
|
||||||
theCommand.cmd = quietCmd;
|
|
||||||
theCommand.param1 = 0;
|
|
||||||
theCommand.param2 = 0L;
|
|
||||||
theErr = SndDoImmediate(musicChannel, &theCommand);
|
|
||||||
|
|
||||||
isMusicOn = false;
|
isMusicOn = false;
|
||||||
}
|
}
|
||||||
@@ -186,13 +156,10 @@ void SetMusicalMode (short newMode)
|
|||||||
|
|
||||||
//-------------------------------------------------------------- MusicCallBack
|
//-------------------------------------------------------------- MusicCallBack
|
||||||
|
|
||||||
void MusicCallBack (SndChannelPtr theChannel, SndCommand *theCommand)
|
void MusicCallBack (PortabilityLayer::AudioChannel *theChannel)
|
||||||
{
|
{
|
||||||
PLError_t theErr;
|
PLError_t theErr;
|
||||||
|
|
||||||
// gameA5 = theCommand.param2;
|
|
||||||
// thisA5 = SetA5(gameA5);
|
|
||||||
|
|
||||||
musicMutex->Lock();
|
musicMutex->Lock();
|
||||||
switch (musicState.musicMode)
|
switch (musicState.musicMode)
|
||||||
{
|
{
|
||||||
@@ -223,15 +190,8 @@ void MusicCallBack (SndChannelPtr theChannel, SndCommand *theCommand)
|
|||||||
short musicSoundID = musicState.musicSoundID;
|
short musicSoundID = musicState.musicSoundID;
|
||||||
musicMutex->Unlock();
|
musicMutex->Unlock();
|
||||||
|
|
||||||
theCommand->cmd = bufferCmd;
|
theChannel->AddBuffer(theMusicData[musicSoundID], true);
|
||||||
theCommand->param1 = 0;
|
theChannel->AddCallback(MusicCallBack, true);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------- LoadMusicSounds
|
//-------------------------------------------------------------- LoadMusicSounds
|
||||||
@@ -256,7 +216,7 @@ PLError_t LoadMusicSounds (void)
|
|||||||
|
|
||||||
soundDataSize = GetHandleSize(theSound) - 20L;
|
soundDataSize = GetHandleSize(theSound) - 20L;
|
||||||
|
|
||||||
theMusicData[i] = NewPtr(soundDataSize);
|
theMusicData[i] = PortabilityLayer::MemoryManager::GetInstance()->Alloc(soundDataSize);
|
||||||
if (theMusicData[i] == nil)
|
if (theMusicData[i] == nil)
|
||||||
return PLErrors::kOutOfMemory;
|
return PLErrors::kOutOfMemory;
|
||||||
|
|
||||||
@@ -278,7 +238,7 @@ PLError_t DumpMusicSounds (void)
|
|||||||
for (i = 0; i < kMaxMusic; i++)
|
for (i = 0; i < kMaxMusic; i++)
|
||||||
{
|
{
|
||||||
if (theMusicData[i] != nil)
|
if (theMusicData[i] != nil)
|
||||||
DisposePtr(theMusicData[i]);
|
PortabilityLayer::MemoryManager::GetInstance()->Release(theMusicData[i]);
|
||||||
theMusicData[i] = nil;
|
theMusicData[i] = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,17 +251,15 @@ PLError_t OpenMusicChannel (void)
|
|||||||
{
|
{
|
||||||
PLError_t theErr;
|
PLError_t theErr;
|
||||||
|
|
||||||
musicCallBackUPP = NewSndCallBackProc(MusicCallBack);
|
|
||||||
|
|
||||||
theErr = PLErrors::kNone;
|
theErr = PLErrors::kNone;
|
||||||
|
|
||||||
if (musicChannel != nil)
|
if (musicChannel != nil)
|
||||||
return (theErr);
|
return (theErr);
|
||||||
|
|
||||||
musicChannel = nil;
|
musicChannel = PortabilityLayer::SoundSystem::GetInstance()->CreateChannel();
|
||||||
theErr = SndNewChannel(&musicChannel,
|
|
||||||
sampledSynth, initNoInterp + initMono,
|
if (musicChannel == nil)
|
||||||
(SndCallBackUPP)musicCallBackUPP);
|
theErr = PLErrors::kAudioError;
|
||||||
|
|
||||||
return (theErr);
|
return (theErr);
|
||||||
}
|
}
|
||||||
@@ -315,11 +273,9 @@ PLError_t CloseMusicChannel (void)
|
|||||||
theErr = PLErrors::kNone;
|
theErr = PLErrors::kNone;
|
||||||
|
|
||||||
if (musicChannel != nil)
|
if (musicChannel != nil)
|
||||||
theErr = SndDisposeChannel(musicChannel, true);
|
musicChannel->Destroy(false);
|
||||||
musicChannel = nil;
|
musicChannel = nil;
|
||||||
|
|
||||||
DisposeSndCallBackUPP(musicCallBackUPP);
|
|
||||||
|
|
||||||
return (theErr);
|
return (theErr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
233
GpApp/Sound.cpp
233
GpApp/Sound.cpp
@@ -9,6 +9,7 @@
|
|||||||
#include "PLResources.h"
|
#include "PLResources.h"
|
||||||
#include "PLSound.h"
|
#include "PLSound.h"
|
||||||
#include "Externs.h"
|
#include "Externs.h"
|
||||||
|
#include "MemoryManager.h"
|
||||||
#include "SoundSync.h"
|
#include "SoundSync.h"
|
||||||
#include "VirtualDirectory.h"
|
#include "VirtualDirectory.h"
|
||||||
|
|
||||||
@@ -17,17 +18,16 @@
|
|||||||
#define kMaxSounds 64
|
#define kMaxSounds 64
|
||||||
|
|
||||||
|
|
||||||
void CallBack0 (SndChannelPtr, SndCommand *);
|
void CallBack0 (PortabilityLayer::AudioChannel *);
|
||||||
void CallBack1 (SndChannelPtr, SndCommand *);
|
void CallBack1 (PortabilityLayer::AudioChannel *);
|
||||||
void CallBack2 (SndChannelPtr, SndCommand *);
|
void CallBack2 (PortabilityLayer::AudioChannel *);
|
||||||
PLError_t LoadBufferSounds (void);
|
PLError_t LoadBufferSounds (void);
|
||||||
void DumpBufferSounds (void);
|
void DumpBufferSounds (void);
|
||||||
PLError_t OpenSoundChannels (void);
|
PLError_t OpenSoundChannels (void);
|
||||||
PLError_t CloseSoundChannels (void);
|
void CloseSoundChannels (void);
|
||||||
|
|
||||||
|
|
||||||
SndCallBackUPP callBack0UPP, callBack1UPP, callBack2UPP;
|
PortabilityLayer::AudioChannel *channel0, *channel1, *channel2;
|
||||||
SndChannelPtr channel0, channel1, channel2;
|
|
||||||
Ptr theSoundData[kMaxSounds];
|
Ptr theSoundData[kMaxSounds];
|
||||||
short numSoundsLoaded;
|
short numSoundsLoaded;
|
||||||
Boolean soundLoaded[kMaxSounds], dontLoadSounds;
|
Boolean soundLoaded[kMaxSounds], dontLoadSounds;
|
||||||
@@ -76,131 +76,97 @@ void PlayPrioritySound (short which, short priority)
|
|||||||
|
|
||||||
void FlushAnyTriggerPlaying (void)
|
void FlushAnyTriggerPlaying (void)
|
||||||
{
|
{
|
||||||
SndCommand theCommand;
|
|
||||||
PLError_t theErr;
|
|
||||||
|
|
||||||
SoundSyncState ss = SoundSync_ReadAll();
|
SoundSyncState ss = SoundSync_ReadAll();
|
||||||
|
|
||||||
if (ss.priority0 == kTriggerPriority)
|
if (ss.priority0 == kTriggerPriority)
|
||||||
{
|
{
|
||||||
theCommand.cmd = quietCmd;
|
channel0->ClearAllCommands();
|
||||||
theCommand.param1 = 0;
|
channel0->Stop();
|
||||||
theCommand.param2 = 0;
|
|
||||||
theErr = SndDoImmediate(channel0, &theCommand);
|
|
||||||
theCommand.cmd = flushCmd;
|
|
||||||
theCommand.param1 = 0;
|
|
||||||
theCommand.param2 = 0;
|
|
||||||
theErr = SndDoImmediate(channel0, &theCommand);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ss.priority1 == kTriggerPriority)
|
if (ss.priority1 == kTriggerPriority)
|
||||||
{
|
{
|
||||||
theCommand.cmd = quietCmd;
|
channel1->ClearAllCommands();
|
||||||
theCommand.param1 = 0;
|
channel1->Stop();
|
||||||
theCommand.param2 = 0;
|
|
||||||
theErr = SndDoImmediate(channel1, &theCommand);
|
|
||||||
theCommand.cmd = flushCmd;
|
|
||||||
theCommand.param1 = 0;
|
|
||||||
theCommand.param2 = 0;
|
|
||||||
theErr = SndDoImmediate(channel1, &theCommand);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ss.priority2 == kTriggerPriority)
|
if (ss.priority2 == kTriggerPriority)
|
||||||
{
|
{
|
||||||
theCommand.cmd = quietCmd;
|
channel2->ClearAllCommands();
|
||||||
theCommand.param1 = 0;
|
channel2->Stop();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------- CallBack0
|
//-------------------------------------------------------------- CallBack0
|
||||||
|
|
||||||
void CallBack0 (SndChannelPtr theChannel, SndCommand *theCommand)
|
void CallBack0(PortabilityLayer::AudioChannel *theChannel)
|
||||||
{
|
{
|
||||||
SoundSync_ClearPriority(0);
|
SoundSync_ClearPriority(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------- CallBack1
|
//-------------------------------------------------------------- CallBack1
|
||||||
|
|
||||||
void CallBack1 (SndChannelPtr theChannel, SndCommand *theCommand)
|
void CallBack1(PortabilityLayer::AudioChannel *theChannel)
|
||||||
{
|
{
|
||||||
SoundSync_ClearPriority(1);
|
SoundSync_ClearPriority(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------- CallBack2
|
//-------------------------------------------------------------- CallBack2
|
||||||
|
|
||||||
void CallBack2 (SndChannelPtr theChannel, SndCommand *theCommand)
|
void CallBack2(PortabilityLayer::AudioChannel *theChannel)
|
||||||
{
|
{
|
||||||
SoundSync_ClearPriority(2);
|
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
|
//-------------------------------------------------------------- LoadTriggerSound
|
||||||
|
|
||||||
PLError_t LoadTriggerSound (short soundID)
|
PLError_t LoadTriggerSound (short soundID)
|
||||||
@@ -225,7 +191,7 @@ PLError_t LoadTriggerSound (short soundID)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
soundDataSize = GetHandleSize(theSound) - 20L;
|
soundDataSize = GetHandleSize(theSound) - 20L;
|
||||||
theSoundData[kMaxSounds - 1] = NewPtr(soundDataSize);
|
theSoundData[kMaxSounds - 1] = PortabilityLayer::MemoryManager::GetInstance()->Alloc(soundDataSize);
|
||||||
if (theSoundData[kMaxSounds - 1] == nil)
|
if (theSoundData[kMaxSounds - 1] == nil)
|
||||||
{
|
{
|
||||||
theSound.Dispose();
|
theSound.Dispose();
|
||||||
@@ -247,7 +213,7 @@ PLError_t LoadTriggerSound (short soundID)
|
|||||||
void DumpTriggerSound (void)
|
void DumpTriggerSound (void)
|
||||||
{
|
{
|
||||||
if (theSoundData[kMaxSounds - 1] != nil)
|
if (theSoundData[kMaxSounds - 1] != nil)
|
||||||
DisposePtr(theSoundData[kMaxSounds - 1]);
|
PortabilityLayer::MemoryManager::GetInstance()->Release(theSoundData[kMaxSounds - 1]);
|
||||||
theSoundData[kMaxSounds - 1] = nil;
|
theSoundData[kMaxSounds - 1] = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,7 +236,7 @@ PLError_t LoadBufferSounds (void)
|
|||||||
|
|
||||||
soundDataSize = GetHandleSize(theSound) - 20L;
|
soundDataSize = GetHandleSize(theSound) - 20L;
|
||||||
|
|
||||||
theSoundData[i] = NewPtr(soundDataSize);
|
theSoundData[i] = PortabilityLayer::MemoryManager::GetInstance()->Alloc(soundDataSize);
|
||||||
if (theSoundData[i] == nil)
|
if (theSoundData[i] == nil)
|
||||||
return (PLErrors::kOutOfMemory);
|
return (PLErrors::kOutOfMemory);
|
||||||
|
|
||||||
@@ -292,7 +258,7 @@ void DumpBufferSounds (void)
|
|||||||
for (i = 0; i < kMaxSounds; i++)
|
for (i = 0; i < kMaxSounds; i++)
|
||||||
{
|
{
|
||||||
if (theSoundData[i] != nil)
|
if (theSoundData[i] != nil)
|
||||||
DisposePtr(theSoundData[i]);
|
PortabilityLayer::MemoryManager::GetInstance()->Release(theSoundData[i]);
|
||||||
theSoundData[i] = nil;
|
theSoundData[i] = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -301,73 +267,50 @@ void DumpBufferSounds (void)
|
|||||||
|
|
||||||
PLError_t OpenSoundChannels (void)
|
PLError_t OpenSoundChannels (void)
|
||||||
{
|
{
|
||||||
PLError_t theErr;
|
|
||||||
|
|
||||||
callBack0UPP = NewSndCallBackProc(CallBack0);
|
|
||||||
callBack1UPP = NewSndCallBackProc(CallBack1);
|
|
||||||
callBack2UPP = NewSndCallBackProc(CallBack2);
|
|
||||||
|
|
||||||
theErr = PLErrors::kNone;
|
|
||||||
|
|
||||||
if (channelOpen)
|
if (channelOpen)
|
||||||
return (theErr);
|
return PLErrors::kAudioError;
|
||||||
|
|
||||||
theErr = SndNewChannel(&channel0,
|
channel0 = PortabilityLayer::SoundSystem::GetInstance()->CreateChannel();
|
||||||
sampledSynth, initNoInterp + initMono,
|
if (channel0)
|
||||||
(SndCallBackUPP)callBack0UPP);
|
|
||||||
if (theErr == PLErrors::kNone)
|
|
||||||
channelOpen = true;
|
channelOpen = true;
|
||||||
else
|
else
|
||||||
return (theErr);
|
return PLErrors::kAudioError;
|
||||||
|
|
||||||
theErr = SndNewChannel(&channel1,
|
channel1 = PortabilityLayer::SoundSystem::GetInstance()->CreateChannel();
|
||||||
sampledSynth, initNoInterp + initMono,
|
if (channel1)
|
||||||
(SndCallBackUPP)callBack1UPP);
|
|
||||||
if (theErr == PLErrors::kNone)
|
|
||||||
channelOpen = true;
|
channelOpen = true;
|
||||||
else
|
else
|
||||||
return (theErr);
|
return PLErrors::kAudioError;
|
||||||
|
|
||||||
theErr = SndNewChannel(&channel2,
|
channel2 = PortabilityLayer::SoundSystem::GetInstance()->CreateChannel();
|
||||||
sampledSynth, initNoInterp + initMono,
|
if (channel2)
|
||||||
(SndCallBackUPP)callBack2UPP);
|
|
||||||
if (theErr == PLErrors::kNone)
|
|
||||||
channelOpen = true;
|
channelOpen = true;
|
||||||
|
else
|
||||||
|
return PLErrors::kAudioError;
|
||||||
|
|
||||||
return (theErr);
|
return PLErrors::kNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------- CloseSoundChannels
|
//-------------------------------------------------------------- CloseSoundChannels
|
||||||
|
|
||||||
PLError_t CloseSoundChannels (void)
|
void CloseSoundChannels (void)
|
||||||
{
|
{
|
||||||
PLError_t theErr;
|
|
||||||
|
|
||||||
theErr = PLErrors::kNone;
|
|
||||||
|
|
||||||
if (!channelOpen)
|
if (!channelOpen)
|
||||||
return (theErr);
|
return;
|
||||||
|
|
||||||
if (channel0 != nil)
|
if (channel0 != nil)
|
||||||
theErr = SndDisposeChannel(channel0, true);
|
channel0->Destroy(false);
|
||||||
channel0 = nil;
|
channel0 = nil;
|
||||||
|
|
||||||
if (channel1 != nil)
|
if (channel1 != nil)
|
||||||
theErr = SndDisposeChannel(channel1, true);
|
channel1->Destroy(false);
|
||||||
channel1 = nil;
|
channel1 = nil;
|
||||||
|
|
||||||
if (channel2 != nil)
|
if (channel2 != nil)
|
||||||
theErr = SndDisposeChannel(channel2, true);
|
channel2->Destroy(false);
|
||||||
channel2 = nil;
|
channel2 = nil;
|
||||||
|
|
||||||
if (theErr == PLErrors::kNone)
|
channelOpen = false;
|
||||||
channelOpen = false;
|
|
||||||
|
|
||||||
DisposeSndCallBackUPP(callBack0UPP);
|
|
||||||
DisposeSndCallBackUPP(callBack1UPP);
|
|
||||||
DisposeSndCallBackUPP(callBack2UPP);
|
|
||||||
|
|
||||||
return (theErr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------- InitSound
|
//-------------------------------------------------------------- InitSound
|
||||||
@@ -411,13 +354,11 @@ void InitSound (void)
|
|||||||
|
|
||||||
void KillSound (void)
|
void KillSound (void)
|
||||||
{
|
{
|
||||||
PLError_t theErr;
|
|
||||||
|
|
||||||
if (dontLoadSounds)
|
if (dontLoadSounds)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DumpBufferSounds();
|
DumpBufferSounds();
|
||||||
theErr = CloseSoundChannels();
|
CloseSoundChannels();
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------- SoundBytesNeeded
|
//-------------------------------------------------------------- SoundBytesNeeded
|
||||||
|
@@ -511,8 +511,8 @@ void UnivGetSoundVolume (short *volume, Boolean hasSM3)
|
|||||||
|
|
||||||
// if (hasSM3)
|
// if (hasSM3)
|
||||||
// {
|
// {
|
||||||
theErr = GetDefaultOutputVolume(&longVol);
|
longVol = PortabilityLayer::SoundSystem::GetInstance()->GetVolume();
|
||||||
*volume = LoWord(longVol) / 0x0024;
|
*volume = longVol / 0x0024;
|
||||||
// }
|
// }
|
||||||
// else
|
// else
|
||||||
// GetSoundVol(volume);
|
// GetSoundVol(volume);
|
||||||
@@ -530,7 +530,6 @@ void UnivGetSoundVolume (short *volume, Boolean hasSM3)
|
|||||||
void UnivSetSoundVolume (short volume, Boolean hasSM3)
|
void UnivSetSoundVolume (short volume, Boolean hasSM3)
|
||||||
{
|
{
|
||||||
long longVol;
|
long longVol;
|
||||||
PLError_t theErr;
|
|
||||||
|
|
||||||
if (volume > 7)
|
if (volume > 7)
|
||||||
volume = 7;
|
volume = 7;
|
||||||
@@ -542,8 +541,8 @@ void UnivSetSoundVolume (short volume, Boolean hasSM3)
|
|||||||
longVol = (long)volume * 0x0025;
|
longVol = (long)volume * 0x0025;
|
||||||
if (longVol > 0x00000100)
|
if (longVol > 0x00000100)
|
||||||
longVol = 0x00000100;
|
longVol = 0x00000100;
|
||||||
longVol = longVol + (longVol << 16);
|
|
||||||
theErr = SetDefaultOutputVolume(longVol);
|
PortabilityLayer::SoundSystem::GetInstance()->SetVolume(longVol);
|
||||||
// }
|
// }
|
||||||
// else
|
// else
|
||||||
// SetSoundVol(volume);
|
// SetSoundVol(volume);
|
||||||
|
@@ -12,25 +12,53 @@
|
|||||||
|
|
||||||
namespace PortabilityLayer
|
namespace PortabilityLayer
|
||||||
{
|
{
|
||||||
class AudioChannelImpl : public SndChannel, public ClientAudioChannelContext
|
namespace AudioCommandTypes
|
||||||
|
{
|
||||||
|
enum AudioCommandType
|
||||||
|
{
|
||||||
|
kBuffer,
|
||||||
|
kCallback,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef AudioCommandTypes::AudioCommandType AudioCommandType_t;
|
||||||
|
|
||||||
|
struct AudioCommand
|
||||||
|
{
|
||||||
|
union AudioCommandParam
|
||||||
|
{
|
||||||
|
const void *m_ptr;
|
||||||
|
AudioChannelCallback_t m_callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
AudioCommandType_t m_commandType;
|
||||||
|
AudioCommandParam m_param;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AudioChannelImpl final : public AudioChannel, public ClientAudioChannelContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit AudioChannelImpl(PortabilityLayer::HostAudioChannel *channel, SndCallBackUPP callback, HostThreadEvent *threadEvent, HostMutex *mutex);
|
explicit AudioChannelImpl(PortabilityLayer::HostAudioChannel *channel, HostThreadEvent *threadEvent, HostMutex *mutex);
|
||||||
~AudioChannelImpl();
|
~AudioChannelImpl();
|
||||||
|
|
||||||
bool PushCommand(const SndCommand &command, bool blocking);
|
void Destroy(bool wait) override;
|
||||||
void ClearAllCommands();
|
bool AddBuffer(const void *smBuffer, bool blocking) override;
|
||||||
void Stop();
|
bool AddCallback(AudioChannelCallback_t callback, bool blocking) override;
|
||||||
|
void ClearAllCommands() override;
|
||||||
|
void Stop() override;
|
||||||
|
|
||||||
void NotifyBufferFinished() override;
|
void NotifyBufferFinished() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool PushCommand(const AudioCommand &command, bool blocking);
|
||||||
|
|
||||||
enum WorkingState
|
enum WorkingState
|
||||||
{
|
{
|
||||||
State_Idle, // No thread is playing sound, the sound thread is out of work
|
State_Idle, // No thread is playing sound, the sound thread is out of work
|
||||||
State_PlayingAsync, // Sound thread is playing sound. When it finishes, it will digest queue events under a lock.
|
State_PlayingAsync, // Sound thread is playing sound. When it finishes, it will digest queue events under a lock.
|
||||||
State_PlayingBlocked, // Sound thread is playing sound. When it finishes, it will transition to Idle and fire the thread event.
|
State_PlayingBlocked, // Sound thread is playing sound. When it finishes, it will transition to Idle and fire the thread event.
|
||||||
State_FlushStarting, // Sound thread is aborting. When it aborts, it will transition to Idle and fire the thread event.
|
State_FlushStarting, // Sound thread is aborting. When it aborts, it will transition to Idle and fire the thread event.
|
||||||
|
State_ShuttingDown, // Sound thread is shutting down. When it finishes, it will transition to idle and fire the thread event.
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned int kMaxQueuedCommands = 64;
|
static const unsigned int kMaxQueuedCommands = 64;
|
||||||
@@ -39,12 +67,12 @@ namespace PortabilityLayer
|
|||||||
void DigestBufferCommand(const void *dataPointer);
|
void DigestBufferCommand(const void *dataPointer);
|
||||||
|
|
||||||
PortabilityLayer::HostAudioChannel *m_audioChannel;
|
PortabilityLayer::HostAudioChannel *m_audioChannel;
|
||||||
SndCallBackUPP m_callback;
|
;
|
||||||
|
|
||||||
HostMutex *m_mutex;
|
HostMutex *m_mutex;
|
||||||
HostThreadEvent *m_threadEvent;
|
HostThreadEvent *m_threadEvent;
|
||||||
|
|
||||||
SndCommand m_commandQueue[kMaxQueuedCommands];
|
AudioCommand m_commandQueue[kMaxQueuedCommands];
|
||||||
size_t m_numQueuedCommands;
|
size_t m_numQueuedCommands;
|
||||||
size_t m_nextInsertCommandPos;
|
size_t m_nextInsertCommandPos;
|
||||||
size_t m_nextDequeueCommandPos;
|
size_t m_nextDequeueCommandPos;
|
||||||
@@ -52,9 +80,8 @@ namespace PortabilityLayer
|
|||||||
bool m_isIdle;
|
bool m_isIdle;
|
||||||
};
|
};
|
||||||
|
|
||||||
AudioChannelImpl::AudioChannelImpl(PortabilityLayer::HostAudioChannel *channel, SndCallBackUPP callback, HostThreadEvent *threadEvent, HostMutex *mutex)
|
AudioChannelImpl::AudioChannelImpl(PortabilityLayer::HostAudioChannel *channel, HostThreadEvent *threadEvent, HostMutex *mutex)
|
||||||
: m_audioChannel(channel)
|
: m_audioChannel(channel)
|
||||||
, m_callback(callback)
|
|
||||||
, m_threadEvent(threadEvent)
|
, m_threadEvent(threadEvent)
|
||||||
, m_mutex(mutex)
|
, m_mutex(mutex)
|
||||||
, m_nextInsertCommandPos(0)
|
, m_nextInsertCommandPos(0)
|
||||||
@@ -81,7 +108,7 @@ namespace PortabilityLayer
|
|||||||
m_state = State_Idle;
|
m_state = State_Idle;
|
||||||
DigestQueueItems();
|
DigestQueueItems();
|
||||||
}
|
}
|
||||||
else if (m_state == State_PlayingBlocked || m_state == State_FlushStarting)
|
else if (m_state == State_PlayingBlocked || m_state == State_FlushStarting || m_state == State_ShuttingDown)
|
||||||
{
|
{
|
||||||
m_state = State_Idle;
|
m_state = State_Idle;
|
||||||
m_threadEvent->Signal();
|
m_threadEvent->Signal();
|
||||||
@@ -90,6 +117,52 @@ namespace PortabilityLayer
|
|||||||
m_mutex->Unlock();
|
m_mutex->Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioChannelImpl::Destroy(bool wait)
|
||||||
|
{
|
||||||
|
ClearAllCommands();
|
||||||
|
|
||||||
|
if (!wait)
|
||||||
|
Stop();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_mutex->Lock();
|
||||||
|
|
||||||
|
if (m_state == State_PlayingAsync)
|
||||||
|
{
|
||||||
|
m_state = State_ShuttingDown;
|
||||||
|
m_mutex->Unlock();
|
||||||
|
|
||||||
|
m_threadEvent->Wait();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(m_state == State_Idle);
|
||||||
|
m_mutex->Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->~AudioChannelImpl();
|
||||||
|
PortabilityLayer::MemoryManager::GetInstance()->Release(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AudioChannelImpl::AddBuffer(const void *smBuffer, bool blocking)
|
||||||
|
{
|
||||||
|
AudioCommand cmd;
|
||||||
|
cmd.m_commandType = AudioCommandTypes::kBuffer;
|
||||||
|
cmd.m_param.m_ptr = smBuffer;
|
||||||
|
|
||||||
|
return this->PushCommand(cmd, blocking);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AudioChannelImpl::AddCallback(AudioChannelCallback_t callback, bool blocking)
|
||||||
|
{
|
||||||
|
AudioCommand cmd;
|
||||||
|
cmd.m_commandType = AudioCommandTypes::kCallback;
|
||||||
|
cmd.m_param.m_ptr = callback;
|
||||||
|
|
||||||
|
return this->PushCommand(cmd, blocking);
|
||||||
|
}
|
||||||
|
|
||||||
void AudioChannelImpl::DigestQueueItems()
|
void AudioChannelImpl::DigestQueueItems()
|
||||||
{
|
{
|
||||||
m_mutex->Lock();
|
m_mutex->Lock();
|
||||||
@@ -98,29 +171,22 @@ namespace PortabilityLayer
|
|||||||
|
|
||||||
while (m_numQueuedCommands > 0)
|
while (m_numQueuedCommands > 0)
|
||||||
{
|
{
|
||||||
const SndCommand &command = m_commandQueue[m_nextDequeueCommandPos];
|
const AudioCommand &command = m_commandQueue[m_nextDequeueCommandPos];
|
||||||
m_numQueuedCommands--;
|
m_numQueuedCommands--;
|
||||||
m_nextDequeueCommandPos = (m_nextDequeueCommandPos + 1) % static_cast<size_t>(kMaxQueuedCommands);
|
m_nextDequeueCommandPos = (m_nextDequeueCommandPos + 1) % static_cast<size_t>(kMaxQueuedCommands);
|
||||||
|
|
||||||
switch (command.cmd)
|
switch (command.m_commandType)
|
||||||
{
|
{
|
||||||
case nullCmd:
|
case AudioCommandTypes::kBuffer:
|
||||||
break;
|
DigestBufferCommand(command.m_param.m_ptr);
|
||||||
case bufferCmd:
|
|
||||||
DigestBufferCommand(reinterpret_cast<const void*>(command.param2));
|
|
||||||
assert(m_state == State_PlayingAsync);
|
assert(m_state == State_PlayingAsync);
|
||||||
m_mutex->Unlock();
|
m_mutex->Unlock();
|
||||||
return;
|
return;
|
||||||
case callBackCmd:
|
case AudioCommandTypes::kCallback:
|
||||||
{
|
command.m_param.m_callback(this);
|
||||||
SndCommand commandCopy = command;
|
|
||||||
m_callback(this, &commandCopy);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case flushCmd:
|
assert(false);
|
||||||
case quietCmd:
|
|
||||||
assert(false); // These shouldn't be in the queue
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,14 +218,14 @@ namespace PortabilityLayer
|
|||||||
m_state = State_PlayingAsync;
|
m_state = State_PlayingAsync;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioChannelImpl::PushCommand(const SndCommand &command, bool failIfFull)
|
bool AudioChannelImpl::PushCommand(const AudioCommand &command, bool blocking)
|
||||||
{
|
{
|
||||||
bool digestOnThisThread = false;
|
bool digestOnThisThread = false;
|
||||||
|
|
||||||
m_mutex->Lock();
|
m_mutex->Lock();
|
||||||
if (m_numQueuedCommands == kMaxQueuedCommands)
|
if (m_numQueuedCommands == kMaxQueuedCommands)
|
||||||
{
|
{
|
||||||
if (failIfFull)
|
if (!blocking)
|
||||||
{
|
{
|
||||||
m_mutex->Unlock();
|
m_mutex->Unlock();
|
||||||
return false;
|
return false;
|
||||||
@@ -250,98 +316,78 @@ PLError_t SetDefaultOutputVolume(long vol)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SndCallBackUPP NewSndCallBackProc(SndCallBackProc callback)
|
namespace PortabilityLayer
|
||||||
{
|
{
|
||||||
return callback;
|
class SoundSystemImpl final : public SoundSystem
|
||||||
}
|
|
||||||
|
|
||||||
void DisposeSndCallBackUPP(SndCallBackUPP upp)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PLError_t SndNewChannel(SndChannelPtr *outChannel, SndSynthType synthType, int initFlags, SndCallBackUPP callback)
|
|
||||||
{
|
|
||||||
PortabilityLayer::MemoryManager *mm = PortabilityLayer::MemoryManager::GetInstance();
|
|
||||||
void *storage = mm->Alloc(sizeof(PortabilityLayer::AudioChannelImpl));
|
|
||||||
if (!storage)
|
|
||||||
return PLErrors::kOutOfMemory;
|
|
||||||
|
|
||||||
PortabilityLayer::HostAudioDriver *audioDriver = PortabilityLayer::HostAudioDriver::GetInstance();
|
|
||||||
PortabilityLayer::HostAudioChannel *audioChannel = audioDriver->CreateChannel();
|
|
||||||
if (!audioChannel)
|
|
||||||
{
|
{
|
||||||
mm->Release(storage);
|
public:
|
||||||
return PLErrors::kAudioError;
|
AudioChannel *CreateChannel() override;
|
||||||
|
|
||||||
|
void SetVolume(uint8_t vol) override;
|
||||||
|
uint8_t GetVolume() const override;
|
||||||
|
|
||||||
|
static SoundSystemImpl *GetInstance();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static SoundSystemImpl ms_instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
AudioChannel *SoundSystemImpl::CreateChannel()
|
||||||
|
{
|
||||||
|
PortabilityLayer::MemoryManager *mm = PortabilityLayer::MemoryManager::GetInstance();
|
||||||
|
void *storage = mm->Alloc(sizeof(PortabilityLayer::AudioChannelImpl));
|
||||||
|
if (!storage)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
PortabilityLayer::HostAudioDriver *audioDriver = PortabilityLayer::HostAudioDriver::GetInstance();
|
||||||
|
PortabilityLayer::HostAudioChannel *audioChannel = audioDriver->CreateChannel();
|
||||||
|
if (!audioChannel)
|
||||||
|
{
|
||||||
|
mm->Release(storage);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PortabilityLayer::HostMutex *mutex = PortabilityLayer::HostSystemServices::GetInstance()->CreateMutex();
|
||||||
|
if (!mutex)
|
||||||
|
{
|
||||||
|
audioChannel->Destroy();
|
||||||
|
mm->Release(storage);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PortabilityLayer::HostThreadEvent *threadEvent = PortabilityLayer::HostSystemServices::GetInstance()->CreateThreadEvent(true, false);
|
||||||
|
if (!threadEvent)
|
||||||
|
{
|
||||||
|
mutex->Destroy();
|
||||||
|
audioChannel->Destroy();
|
||||||
|
mm->Release(storage);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new (storage) PortabilityLayer::AudioChannelImpl(audioChannel, threadEvent, mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
PortabilityLayer::HostMutex *mutex = PortabilityLayer::HostSystemServices::GetInstance()->CreateMutex();
|
|
||||||
if (!mutex)
|
void SoundSystemImpl::SetVolume(uint8_t vol)
|
||||||
{
|
{
|
||||||
audioChannel->Destroy();
|
PL_NotYetImplemented_TODO("Volume");
|
||||||
mm->Release(storage);
|
|
||||||
return PLErrors::kAudioError;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PortabilityLayer::HostThreadEvent *threadEvent = PortabilityLayer::HostSystemServices::GetInstance()->CreateThreadEvent(true, false);
|
uint8_t SoundSystemImpl::GetVolume() const
|
||||||
if (!threadEvent)
|
|
||||||
{
|
{
|
||||||
mutex->Destroy();
|
PL_NotYetImplemented_TODO("Volume");
|
||||||
audioChannel->Destroy();
|
return 255;
|
||||||
mm->Release(storage);
|
|
||||||
return PLErrors::kAudioError;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*outChannel = new (storage) PortabilityLayer::AudioChannelImpl(audioChannel, callback, threadEvent, mutex);
|
SoundSystemImpl *SoundSystemImpl::GetInstance()
|
||||||
|
|
||||||
return PLErrors::kNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
PLError_t SndDisposeChannel(SndChannelPtr channel, Boolean flush)
|
|
||||||
{
|
|
||||||
if (flush)
|
|
||||||
{
|
{
|
||||||
SndCommand cmd;
|
return &ms_instance;
|
||||||
cmd.cmd = flushCmd;
|
|
||||||
cmd.param1 = cmd.param2 = 0;
|
|
||||||
|
|
||||||
SndDoImmediate(channel, &cmd);
|
|
||||||
|
|
||||||
cmd.cmd = quietCmd;
|
|
||||||
cmd.param1 = cmd.param2 = 0;
|
|
||||||
SndDoImmediate(channel, &cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PortabilityLayer::AudioChannelImpl *audioChannelImpl = static_cast<PortabilityLayer::AudioChannelImpl*>(channel);
|
SoundSystemImpl SoundSystemImpl::ms_instance;
|
||||||
audioChannelImpl->~AudioChannelImpl();
|
|
||||||
|
|
||||||
PortabilityLayer::MemoryManager::GetInstance()->Release(audioChannelImpl);
|
SoundSystem *SoundSystem::GetInstance()
|
||||||
|
|
||||||
return PLErrors::kNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
PLError_t SndDoCommand(SndChannelPtr channel, const SndCommand *command, Boolean failIfFull)
|
|
||||||
{
|
|
||||||
PortabilityLayer::AudioChannelImpl *audioChannelImpl = static_cast<PortabilityLayer::AudioChannelImpl*>(channel);
|
|
||||||
|
|
||||||
if (!audioChannelImpl->PushCommand(*command, failIfFull == 0))
|
|
||||||
return PLErrors::kAudioError;
|
|
||||||
|
|
||||||
return PLErrors::kNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
PLError_t SndDoImmediate(SndChannelPtr channel, const SndCommand *command)
|
|
||||||
{
|
|
||||||
PortabilityLayer::AudioChannelImpl *audioChannelImpl = static_cast<PortabilityLayer::AudioChannelImpl*>(channel);
|
|
||||||
|
|
||||||
if (command->cmd == flushCmd)
|
|
||||||
audioChannelImpl->ClearAllCommands();
|
|
||||||
else if (command->cmd == quietCmd)
|
|
||||||
audioChannelImpl->Stop();
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
assert(false);
|
return SoundSystemImpl::GetInstance();
|
||||||
return PLErrors::kAudioError;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return PLErrors::kNone;
|
|
||||||
}
|
}
|
||||||
|
@@ -1,56 +1,30 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#ifndef __PL_SOUND_H__
|
|
||||||
#define __PL_SOUND_H__
|
|
||||||
|
|
||||||
#include "PLCore.h"
|
#include "PLCore.h"
|
||||||
|
|
||||||
enum SndCommandType
|
namespace PortabilityLayer
|
||||||
{
|
{
|
||||||
nullCmd,
|
struct AudioChannel;
|
||||||
bufferCmd, // Param1: 0 Param2: Offset to sound header
|
|
||||||
callBackCmd,
|
|
||||||
flushCmd,
|
|
||||||
quietCmd
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SndChannel
|
typedef void (*AudioChannelCallback_t)(PortabilityLayer::AudioChannel *channel);
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SndCommand
|
struct AudioChannel
|
||||||
{
|
{
|
||||||
SndCommandType cmd;
|
virtual void Destroy(bool wait) = 0;
|
||||||
intptr_t param1;
|
virtual bool AddBuffer(const void *smBuffer, bool blocking) = 0;
|
||||||
intptr_t param2;
|
virtual bool AddCallback(AudioChannelCallback_t callback, bool blocking) = 0;
|
||||||
};
|
virtual void ClearAllCommands() = 0;
|
||||||
|
virtual void Stop() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
enum SndSynthType
|
class SoundSystem
|
||||||
{
|
{
|
||||||
sampledSynth
|
public:
|
||||||
};
|
virtual AudioChannel *CreateChannel() = 0;
|
||||||
|
|
||||||
enum SndInitFlags
|
virtual void SetVolume(uint8_t vol) = 0;
|
||||||
{
|
virtual uint8_t GetVolume() const = 0;
|
||||||
initNoInterp = 1,
|
|
||||||
initMono = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef SndChannel *SndChannelPtr;
|
static SoundSystem *GetInstance();
|
||||||
|
};
|
||||||
typedef void(*SndCallBackProc)(SndChannelPtr channel, SndCommand *command);
|
}
|
||||||
typedef SndCallBackProc SndCallBackUPP;
|
|
||||||
|
|
||||||
// Vol seems to be a packed stereo DWord
|
|
||||||
|
|
||||||
PLError_t GetDefaultOutputVolume(long *vol);
|
|
||||||
PLError_t SetDefaultOutputVolume(long vol);
|
|
||||||
|
|
||||||
|
|
||||||
SndCallBackUPP NewSndCallBackProc(SndCallBackProc callback);
|
|
||||||
void DisposeSndCallBackUPP(SndCallBackUPP upp);
|
|
||||||
PLError_t SndNewChannel(SndChannelPtr *outChannel, SndSynthType synthType, int initFlags, SndCallBackUPP callback);
|
|
||||||
PLError_t SndDisposeChannel(SndChannelPtr channel, Boolean flush);
|
|
||||||
PLError_t SndDoCommand(SndChannelPtr channel, const SndCommand *command, Boolean failIfFull);
|
|
||||||
PLError_t SndDoImmediate(SndChannelPtr channel, const SndCommand *command);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@@ -194,7 +194,6 @@
|
|||||||
<ClInclude Include="PLDialogs.h" />
|
<ClInclude Include="PLDialogs.h" />
|
||||||
<ClInclude Include="PLErrorCodes.h" />
|
<ClInclude Include="PLErrorCodes.h" />
|
||||||
<ClInclude Include="PLEventQueue.h" />
|
<ClInclude Include="PLEventQueue.h" />
|
||||||
<ClInclude Include="PLFolders.h" />
|
|
||||||
<ClInclude Include="PLHacks.h" />
|
<ClInclude Include="PLHacks.h" />
|
||||||
<ClInclude Include="PLHandle.h" />
|
<ClInclude Include="PLHandle.h" />
|
||||||
<ClInclude Include="PLKeyEncoding.h" />
|
<ClInclude Include="PLKeyEncoding.h" />
|
||||||
|
@@ -123,9 +123,6 @@
|
|||||||
<ClInclude Include="PLTextUtils.h">
|
<ClInclude Include="PLTextUtils.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="PLFolders.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="PLScript.h">
|
<ClInclude Include="PLScript.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
Reference in New Issue
Block a user