Descent3/mac/MAC_LLSOUND.CPP
2024-04-16 12:56:40 -06:00

928 lines
31 KiB
C++

/*
* $Logfile: /DescentIII/Main/mac/MAC_LLSOUND.CPP $
* $Revision: 1.1.1.1 $
* $Date: 2003/08/26 03:58:16 $
* $Author: kevinb $
*
* Mac implementation of low level sound library
*
* $Log: MAC_LLSOUND.CPP,v $
* Revision 1.1.1.1 2003/08/26 03:58:16 kevinb
* initial 1.5 import
*
*
* 4 4/18/00 12:58p Matt
* Another update from Duane for 1.4
*
* 3 4/12/00 7:08p Matt
* From Duane for 1.4
*
* 2 10/21/99 1:55p Kevin
* Mac Merge!
*
* 1 7/28/99 2:31p Kevin
* Mac only stuff
*
* 1 5/21/97 6:53 PM Jeremy
*
* $NoKeywords: $
*/
#include <Sound.h>
#include <SoundSprocket.h>
#include <SoundComponents.h>
#include "pserror.h"
#include "mem.h"
#include "mac_llsound.h"
#include "ssl_lib.h" // Shared sound header (between high and low-levels)
#define REF_DIST 50
#define CLIP_ATTENUATION 0.7f // look in ddsoundload.cpp for its twin
long master_volume_save = -1;
int saveSampleRate;
Component defaultSoundOutputDevice;
pascal void SoundCallBack(SndChannelPtr channel, SndCommand cmd) {
// long sound_uid = (long)channel->userInfo;
channel->userInfo = -1; // set it to negative one to indicate I'm through with you
// channel->userInfo = -channel->userInfo; //set it to negative to indicate I'm through with you
}
void SetLLMasterVolume(float volume) {
short one_side;
long both_side;
if (master_volume_save == -1)
GetDefaultOutputVolume(&master_volume_save);
one_side = volume * 0x0100;
both_side = (one_side << 16) | one_side;
SetDefaultOutputVolume(both_side);
}
void mac_llsSystem::SetSoundCard(const char *name) { sndsprk_initialized = false; }
// Starts the sound library, maybe have it send back some information -- 3d support?
// mac_llsSystem::InitSoundLib(oeApplication *sos, char mixer_type, char m_sound_quality, bool f_kill_sound_list)
int mac_llsSystem::InitSoundLib(char mixer_type, oeApplication *sos, ubyte max_sounds_played) {
int i;
OSStatus err = noErr;
extern UInt16 gNumTracks;
if (sndsprk_initialized) {
if (max_sounds_played != m_channel_count) {
SetNumChannels(max_sounds_played);
return 1;
} else {
return 0;
}
}
sndsprk_initialized = true;
ll_sound_ptr = this;
m_in_sound_frame = false;
m_pending_actions = false;
m_channel_count = 0;
m_mixer_type = SOUND_MIXER_NONE;
if (master_volume_save == -1)
GetDefaultOutputVolume(&master_volume_save);
ComponentDescription theDesc = {kSoundOutputDeviceType, 0, 0, 0, 0};
defaultSoundOutputDevice = FindNextComponent(NULL, &theDesc);
err = GetSoundOutputInfo(defaultSoundOutputDevice, siSampleRate, &saveSampleRate);
if (err)
mprintf((1, "InitSoundLib: unable st Get output rate\n"));
err = SetSoundOutputInfo(defaultSoundOutputDevice, siSampleRate, (void *)rate22050hz);
if (err)
mprintf((1, "InitSoundLib: unable st set output rate\n"));
for (i = 0; i < 3; i++) {
snd_localization[i].cpuLoad = 1;
snd_localization[i].medium = kSSpMedium_Air;
snd_localization[i].humidity = 0;
snd_localization[i].roomSize = 0;
snd_localization[i].roomReflectivity = 0;
snd_localization[i].reverbAttenuation = 0;
snd_localization[i].sourceMode = kSSpSourceMode_Localized;
snd_localization[i].referenceDistance = REF_DIST;
snd_localization[i].coneAngleCos = 0;
snd_localization[i].coneAttenuation = 0;
snd_localization[i].currentLocation.elevation = 0;
snd_localization[i].currentLocation.azimuth = 0;
snd_localization[i].currentLocation.distance = 0;
snd_localization[i].currentLocation.projectionAngle = 1;
snd_localization[i].currentLocation.sourceVelocity = 0;
snd_localization[i].currentLocation.listenerVelocity = 0;
}
snd_localization[SQT_LOW].sourceMode = kSSpSourceMode_Unfiltered;
SetNumChannels(max_sounds_played);
#ifdef SPROCKET17
SSpListener_New(&m_lr);
SSpListener_SetMetersPerUnit(m_lr, 1);
SSpListener_SetReverb(m_lr, 0.0, 0.0, 0.0);
for (i = 0; i < MAX_SOUNDS_MIXED; i++) {
SSpSource_New(&m_sr[i]);
SSpSource_SetMode(m_sr[i], kSSpSourceMode_Localized);
// SSpSource_SetSize(m_sr[i], 0.0, 0.0, 0.0);
// SSpSource_SetAngularAttenuation(m_sr[i], 0.0, 0.0);
}
#endif
return 1;
}
// Cleans up after the Sound Library
void mac_llsSystem::DestroySoundLib(void) {
int i;
if (!sndsprk_initialized)
return;
#ifdef SPROCKET17
if (m_sound_quality == SQT_HIGH) {
SSpListener_Dispose(m_lr);
for (i = 0; i < MAX_SOUNDS_MIXED; i++) {
snd_channel[i] = NULL;
SSpSource_Dispose(m_sr[i]);
}
}
#endif
for (i = 0; i < m_channel_count; i++) {
if (snd_channel[i]) {
SndDisposeChannel(snd_channel[i], true);
}
}
SetDefaultOutputVolume(master_volume_save);
OSStatus err = noErr;
err = SetSoundOutputInfo(defaultSoundOutputDevice, siSampleRate, (void *)saveSampleRate);
if (err)
Error("InitSoundLib: unable to set output rate on exit\n");
}
void mac_llsSystem::SetChannelVolume(int channel, float volume) {
SndCommand sndCommand;
OSErr err;
short one_side = volume * 0x0100;
long both_side = (one_side << 16) | one_side;
sndCommand.cmd = volumeCmd;
sndCommand.param1 = 0;
sndCommand.param2 = both_side;
err = SndDoImmediate(snd_channel[channel], &sndCommand);
if (err)
Error("Sound Channel %d is corrupt: volume", channel);
}
void mac_llsSystem::PlaySound(int file_index, int channel, bool f_looped) {
SndCommand sndCommand;
ExtSoundHeader sndHeader;
OSStatus err;
if (file_index < 0)
return;
if (SoundFiles[file_index].sample_16bit) {
sndHeader.sampleSize = 16;
sndHeader.samplePtr = (char *)SoundFiles[file_index].sample_16bit;
} else if (SoundFiles[file_index].sample_8bit) {
sndHeader.sampleSize = 8;
sndHeader.samplePtr = (char *)SoundFiles[file_index].sample_8bit;
} else
Error("No sound data available");
sndHeader.numFrames = SoundFiles[file_index].np_sample_length;
sndHeader.numChannels = 1;
// sndHeader.sampleRate = rate44khz;
sndHeader.sampleRate = rate22050hz;
sndHeader.encode = extSH;
sndHeader.baseFrequency = kMiddleC;
sndHeader.markerChunk = NULL;
sndHeader.loopStart = 0;
sndHeader.loopEnd = sndHeader.numFrames;
// snd_channel[channel]->userInfo = file_index;
snd_channel[channel]->userInfo = (file_index << 5) | channel;
// long sound_uid = (file_index<<5) | channel;
// snd_channel[channel]->userInfo = sound_uid;
// mprintf((2, "P %d ch %d\n", file_index, channel));
looped[channel] = f_looped;
sndCommand.cmd = flushCmd;
sndCommand.param1 = 0;
sndCommand.param2 = 0L;
err = SndDoImmediate(snd_channel[channel], &sndCommand);
if (err)
Error("Sound Channel %d is corrupt: flushCmd", channel);
sndCommand.cmd = quietCmd;
sndCommand.param1 = 0;
sndCommand.param2 = 0L;
err = SndDoImmediate(snd_channel[channel], &sndCommand);
if (err)
Error("Sound Channel %d is corrupt: quietCmd", channel);
sndCommand.cmd = bufferCmd;
sndCommand.param1 = 0;
sndCommand.param2 = (long)(&sndHeader);
err = SndDoCommand(snd_channel[channel], &sndCommand, true);
if (err)
Error("Sound Channel %d is corrupt: bufferCmd", channel);
if (f_looped) {
sndCommand.cmd = freqCmd;
sndCommand.param1 = 0;
sndCommand.param2 = 60L;
} else {
sndCommand.cmd = callBackCmd;
sndCommand.param1 = 0;
sndCommand.param2 = 0L;
}
err = SndDoCommand(snd_channel[channel], &sndCommand, true);
if (err)
Error("Sound Channel %d is corrupt: bufferCmd", channel);
}
int mac_llsSystem::PlayStream(play_information *play_info) { return 0; }
// Plays a 2d sound
int mac_llsSystem::PlaySound2d(play_information *play_info, int sound_index, float volume, float pan, bool f_looped) {
int channel;
if (sound_index < 0)
return -1;
int file_index = Sounds[sound_index].sample_index;
// do common processing.
if (SoundFiles[file_index].used == 0) {
mprintf((2, "Tryed to play %d sound, it DNE.\n", file_index));
return -1;
}
if (volume < 0.01)
return -1;
channel = FindFreeChannel(volume, play_info->priority);
if (channel == -1)
return -1;
channel_snd_index[channel] = sound_index;
sound_priority[channel] = play_info->priority;
channel_priority[channel] = volume * sound_priority[channel];
mprintf((1, "2d%4d L%d %16s pri %d vol %.2f\n", file_index, f_looped, SoundFiles[file_index].name,
play_info->priority, volume));
#ifdef SPROCKET17
if (m_sound_quality == SQT_HIGH || m_sound_quality == SQT_NORMAL)
#else
if (m_sound_quality == SQT_HIGH)
#endif
{
SetChannelVolume(channel, 2.0);
snd_localization[m_sound_quality].currentLocation.azimuth = pan * PIOVER2;
snd_localization[m_sound_quality].currentLocation.elevation = 0;
snd_localization[m_sound_quality].referenceDistance = 1;
snd_localization[m_sound_quality].currentLocation.distance = volume;
SndSetInfo(snd_channel[channel], siSSpLocalization, &snd_localization[m_sound_quality]);
// mprintf((2, "2d %3d ch %2d d %8.3f pan %f9.4\n", sound_index, channel,
// snd_localization[m_sound_quality].currentLocation.azimuth, volume));
} else {
SetChannelVolume(channel, volume);
}
PlaySound(file_index, channel, f_looped);
return (snd_channel[channel]->userInfo);
}
// Plays a 3d sound
int mac_llsSystem::PlaySound3d(play_information *play_info, int sound_index, pos_state *cur_pos, float master_volume,
bool f_looped, float reverb) {
int channel;
float volume;
if (sound_index < 0)
return -1;
// do common processing.
if (SoundFiles[Sounds[sound_index].sample_index].used == 0) {
mprintf((2, "Tryed to play %d sound, it DNE.\n", sound_index));
return -1;
}
int file_index = Sounds[sound_index].sample_index;
float min = Sounds[sound_index].min_distance;
float max = Sounds[sound_index].max_distance;
vector dir_to_sound = *cur_pos->position - m_emulated_listener.position;
float dist = vm_NormalizeVectorFast(&dir_to_sound);
if (dist < 0.1)
dir_to_sound = m_emulated_listener.orient.fvec;
if (dist >= Sounds[sound_index].max_distance)
return -1;
else if (dist < Sounds[sound_index].min_distance)
volume = 1.0;
else
volume = (1.0 - ((dist - min) / (max - min)));
// if(volume < 0.01) {
// mprintf((1, "SMALL VOL %d %f\n", file_index, volume));
// return -1;
// }
channel = FindFreeChannel(volume, play_info->priority);
if (channel == -1) {
return -1;
}
channel_snd_index[channel] = sound_index;
sound_priority[channel] = play_info->priority;
channel_priority[channel] = volume * sound_priority[channel];
// mprintf((2, "ply %d chn %d vol %f pri %d\n", file_index, channel, volume, play_info->priority));
// mprintf((1, "3d%4d L%d %16s dist %.5f (%.5f,%.5f) pri %d, vol %.5f\n", file_index, f_looped,
//SoundFiles[file_index].name, dist, min, max, play_info->priority, volume));
#ifdef SPROCKET17
if (m_sound_quality == SQT_HIGH) {
// mprintf((1, "SRC %.5f %.5f %.5f ",cur_pos->position->x, cur_pos->position->y, cur_pos->position->z));
// mprintf((1, "LST %.5f %.5f %.5f\n", m_emulated_listener.position.x, m_emulated_listener.position.y,
//m_emulated_listener.position.z));
SSpSource_SetPosition3f(m_sr[channel], cur_pos->position->x, cur_pos->position->y, cur_pos->position->z);
SSpSource_SetOrientation3f(m_sr[channel], cur_pos->orient->fvec.x, cur_pos->orient->fvec.y,
cur_pos->orient->fvec.z);
SSpSource_SetUpVector3f(m_sr[channel], cur_pos->orient->uvec.x, cur_pos->orient->uvec.y, cur_pos->orient->uvec.z);
SSpSource_SetVelocity3f(m_sr[channel], 0, 0, 0);
// SSpSource_SetVelocity3f(m_sr[channel], cur_pos->velocity->x, cur_pos->velocity->y,
//cur_pos->velocity->z);
SSpSource_SetReferenceDistance(m_sr[channel], (max) / DIST_SCALE);
SSpSource_CalcLocalization(m_sr[channel], m_lr, &snd_localization[m_sound_quality]);
SndSetInfo(snd_channel[channel], siSSpLocalization, &snd_localization[m_sound_quality]);
} else if (m_sound_quality == SQT_NORMAL)
#else
if (m_sound_quality == SQT_HIGH)
#endif
{
float az = (dir_to_sound * m_emulated_listener.orient.rvec);
float el = (dir_to_sound * m_emulated_listener.orient.uvec);
if (el > PIOVER2)
el = PIOVER2;
else if (el < PIOVER2)
el = -PIOVER2;
snd_localization[m_sound_quality].referenceDistance = (max) / DIST_SCALE;
snd_localization[m_sound_quality].currentLocation.distance = dist;
snd_localization[m_sound_quality].currentLocation.azimuth = az;
snd_localization[m_sound_quality].currentLocation.elevation = el;
SndSetInfo(snd_channel[channel], siSSpLocalization, &snd_localization[m_sound_quality]);
} else {
SetChannelVolume(channel, volume);
}
PlaySound(file_index, channel, f_looped);
return (snd_channel[channel]->userInfo);
}
// Sync's a single sound (changes something - frequency, volume, pan 3d stuff)
void mac_llsSystem::AdjustSound(int sound_uid, float volume, float pan, unsigned short frequency) {
int channel;
if (sound_uid < 0)
return;
for (int channel = 0; channel < m_channel_count; channel++) {
if (snd_channel[channel]->userInfo == sound_uid) {
channel_priority[channel] = volume * sound_priority[channel];
#ifdef SPROCKET17
if (m_sound_quality == SQT_NORMAL || m_sound_quality == SQT_HIGH)
#else
if (m_sound_quality == SQT_HIGH)
#endif
{
SetChannelVolume(channel, 2.0);
snd_localization[m_sound_quality].currentLocation.azimuth = pan * PIOVER2;
snd_localization[m_sound_quality].currentLocation.elevation = 0;
snd_localization[m_sound_quality].referenceDistance = 1.0;
snd_localization[m_sound_quality].currentLocation.distance = volume;
SndSetInfo(snd_channel[channel], siSSpLocalization, &snd_localization[m_sound_quality]);
// mprintf((2, "adj2d %3d ch %2d d %8.3f pan %f9.4\n", sound_uid, channel,
// snd_localization[SQT_NORMAL].currentLocation.azimuth, volume));
} else {
SetChannelVolume(channel, volume);
}
// break;
}
}
}
void mac_llsSystem::AdjustSound(int sound_uid, pos_state *cur_pos, float adjusted_volume, float reverb) {
int channel;
float volume;
if (sound_uid < 0)
return;
vector dir_to_sound = *cur_pos->position - m_emulated_listener.position;
float dist = vm_NormalizeVectorFast(&dir_to_sound);
if (dist < 0.1)
dir_to_sound = m_emulated_listener.orient.fvec;
for (channel = 0; channel < m_channel_count; channel++) {
if (snd_channel[channel]->userInfo == sound_uid) {
float min = Sounds[channel_snd_index[channel]].min_distance;
float max = Sounds[channel_snd_index[channel]].max_distance;
if (dist >= max) {
// mprintf((1, " %d %.4f >MAX %.4f\n", sound_uid, dist, max));
StopSound(sound_uid);
continue;
} else if (dist < min)
volume = 1.0;
else
volume = (1.0 - ((dist - min) / (max - min)));
// if(volume <= 0.01) {
// mprintf((2, "SMALL VOL %d %.3f dist %.3f (%.3f %.3f)\n", sound_uid, volume,
//dist, min, max)); StopSound(sound_uid); continue;
// }
channel_priority[channel] = volume * sound_priority[channel];
#ifdef SPROCKET17
if (m_sound_quality == SQT_HIGH) {
SSpSource_SetPosition3f(m_sr[channel], cur_pos->position->x, cur_pos->position->y, cur_pos->position->z);
SSpSource_SetOrientation3f(m_sr[channel], cur_pos->orient->fvec.x, cur_pos->orient->fvec.y,
cur_pos->orient->fvec.z);
SSpSource_SetUpVector3f(m_sr[channel], cur_pos->orient->uvec.x, cur_pos->orient->uvec.y,
cur_pos->orient->uvec.z);
// SSpSource_SetVelocity3f(m_sr[channel], 0, 0, 0);
SSpSource_SetVelocity3f(m_sr[channel], cur_pos->velocity->x, cur_pos->velocity->y, cur_pos->velocity->z);
SSpSource_CalcLocalization(m_sr[channel], m_lr, &snd_localization[m_sound_quality]);
SndSetInfo(snd_channel[channel], siSSpLocalization, &snd_localization[m_sound_quality]);
} else if (m_sound_quality == SQT_NORMAL)
#else
if (m_sound_quality == SQT_HIGH)
#endif
{
float az = (dir_to_sound * m_emulated_listener.orient.rvec);
float el = (dir_to_sound * m_emulated_listener.orient.uvec);
if (el > PIOVER2)
el = PIOVER2;
else if (el < -PIOVER2)
el = -PIOVER2;
snd_localization[m_sound_quality].currentLocation.distance = dist;
snd_localization[m_sound_quality].currentLocation.azimuth = az;
snd_localization[m_sound_quality].currentLocation.elevation = el;
SndSetInfo(snd_channel[channel], siSSpLocalization, &snd_localization[m_sound_quality]);
} else {
SetChannelVolume(channel, volume);
}
// break;
}
}
}
// Changes the sound list -- cmphack
void mac_llsSystem::NewSoundList(unsigned short num_sounds, unsigned int *sound_offset_array, char *sound_data,
unsigned int sound_data_size) {}
// Locks and unlocks sounds (used when changing play_info data)
bool mac_llsSystem::LockSound(int sound_uid) { return false; }
bool mac_llsSystem::UnlockSound(int sound_uid) { return false; }
bool mac_llsSystem::SetSoundQuality(char quality) {
int i;
OSErr err;
if (quality == m_sound_quality)
return true;
// pause any sounds that may be playing
PauseSounds();
if (quality == SQT_NORMAL) {
m_sound_quality = SQT_NORMAL;
} else if (quality == SQT_LOW) {
m_sound_quality = SQT_LOW;
} else {
m_sound_quality = SQT_HIGH;
}
if (sndsprk_initialized) {
for (i = 0; i < m_channel_count; i++) {
#ifdef SPROCKET17
if (m_sound_quality == SQT_HIGH || m_sound_quality == SQT_NORMAL)
#else
if (m_sound_quality == SQT_HIGH)
#endif
SetChannelVolume(i, 2.0);
else
SetChannelVolume(i, 0.5);
err = SndSetInfo(snd_channel[i], siSSpLocalization, &snd_localization[m_sound_quality]);
if (err)
Error("unable to localize sound channel %d\n", i);
}
}
#if 1
for (i = 0; i < MAX_SOUNDS; i++) {
if (Sounds[i].used != 0 && Sounds[i].sample_index > -1) {
int snd_index = Sounds[i].sample_index;
ASSERT(snd_index < MAX_SOUNDS);
if (SoundFiles[snd_index].sample_8bit && (m_sound_quality == SQT_HIGH || m_sound_quality == SQT_NORMAL)) {
mem_free(SoundFiles[snd_index].sample_8bit);
SoundFiles[snd_index].sample_8bit = NULL;
CheckAndForceSoundDataAlloc(i);
} else if (SoundFiles[snd_index].sample_16bit && m_sound_quality == SQT_LOW) {
int count;
ASSERT(SoundFiles[snd_index].sample_8bit == NULL);
SoundFiles[snd_index].sample_8bit = (unsigned char *)mem_malloc(SoundFiles[snd_index].sample_length);
// Do the volume clipping with the high quality sound
for (count = 0; count < (int)SoundFiles[snd_index].sample_length; count++) {
SoundFiles[snd_index].sample_16bit[count] *= CLIP_ATTENUATION;
}
// NOTE: Interesting note on sound conversion: 16 bit sounds are signed (0 biase). 8 bit sounds are unsigned
// (+128 biase).
for (count = 0; count < (int)SoundFiles[snd_index].sample_length; count++) {
SoundFiles[snd_index].sample_8bit[count] =
(unsigned char)((((int)SoundFiles[snd_index].sample_16bit[count]) + 32767) >> 8);
}
mem_free(SoundFiles[snd_index].sample_16bit);
SoundFiles[snd_index].sample_16bit = NULL;
}
}
}
#endif
ResumeSounds();
return true;
}
char mac_llsSystem::GetSoundQuality(void) { return m_sound_quality; }
bool mac_llsSystem::SetSoundMixer(char mixer_type) { return true; }
char mac_llsSystem::GetSoundMixer(void) { return SOUND_MIXER_SOFTWARE_16; }
void mac_llsSystem::StopAllSounds(void) {
int i;
SndCommand sndCommand;
OSErr err;
for (i = 0; i < m_channel_count; i++) {
if (snd_channel[i]->userInfo > 0) {
sndCommand.cmd = flushCmd;
sndCommand.param1 = 0;
sndCommand.param2 = 0L;
err = SndDoImmediate(snd_channel[i], &sndCommand);
if (err)
Error("Sound Channel %d is corrupt: flushCmd", i);
sndCommand.cmd = quietCmd;
sndCommand.param1 = 0;
sndCommand.param2 = 0L;
err = SndDoImmediate(snd_channel[i], &sndCommand);
if (err)
Error("Sound Channel %d is corrupt: quietCmd", i);
snd_channel[i]->userInfo = -1;
channel_priority[i] = 0;
}
}
}
// Stops 2d and 3d sounds
void mac_llsSystem::StopSound(int sound_uid, unsigned char f_immediately) {
int i;
SndCommand sndCommand;
OSErr err;
if (sound_uid < 0)
return;
for (i = 0; i < m_channel_count; i++) {
// mprintf((2, "%4d:%.5f ", snd_channel[i]->userInfo, channel_priority[i]));
if ((snd_channel[i]->userInfo) == sound_uid) {
// mprintf((2, "stp %d chn %d\n", snd_channel[i]->userInfo, i));
// long sound_index = (long)ABS(snd_channel[i]->userInfo);
// mprintf((1, "S (ch %d %d) %ld\n", i, sound_index & 0x000f, sound_index>>4 ));
if (f_immediately == SKT_STOP_AFTER_LOOP) {
if (looped[i] == false)
return;
sndCommand.cmd = freqCmd;
sndCommand.param1 = 0;
sndCommand.param2 = 0L;
err = SndDoCommand(snd_channel[i], &sndCommand, true);
if (err)
Error("Sound Channel %d is corrupt: freqCmd", i);
} else {
sndCommand.cmd = flushCmd;
sndCommand.param1 = 0;
sndCommand.param2 = 0L;
err = SndDoImmediate(snd_channel[i], &sndCommand);
if (err)
Error("Sound Channel %d is corrupt: flushCmd", i);
sndCommand.cmd = quietCmd;
sndCommand.param1 = 0;
sndCommand.param2 = 0L;
err = SndDoImmediate(snd_channel[i], &sndCommand);
if (err)
Error("Sound Channel %d is corrupt: quietCmd", i);
}
snd_channel[i]->userInfo = -1;
// snd_channel[i]->userInfo = -snd_channel[i]->userInfo;
channel_priority[i] = 0;
sound_priority[i] = 0;
channel_snd_index[i] = -1;
// return;
}
}
// mprintf((2, "\n"));
}
// Checks if a sound is playing (removes finished sound);
bool mac_llsSystem::IsSoundInstancePlaying(int sound_uid) {
int i;
if (sound_uid < 0)
return false;
for (i = 0; i < m_channel_count; i++) {
if (snd_channel[i]->userInfo == sound_uid) {
return true;
}
}
return false;
}
int mac_llsSystem::IsSoundPlaying(int sound_uid) {
int i;
if (sound_uid < 0)
return -1;
for (i = 0; i < m_channel_count; i++) {
if (snd_channel[i]->userInfo == sound_uid) {
return snd_channel[i]->userInfo;
}
}
return -1;
}
// Set listener's position
void mac_llsSystem::SetListener(pos_state *cur_pos) {
m_emulated_listener.orient = *cur_pos->orient;
m_emulated_listener.position = *cur_pos->position;
m_emulated_listener.velocity = *cur_pos->velocity;
// m_emulated_listener.velocity.x = 0;
// m_emulated_listener.velocity.y = 0;
// m_emulated_listener.velocity.z = 0;
#ifdef SPROCKET17
if (m_sound_quality == SQT_HIGH) {
SSpListener_SetPosition3f(m_lr, m_emulated_listener.position.x, m_emulated_listener.position.y,
m_emulated_listener.position.z);
SSpListener_SetOrientation3f(m_lr, m_emulated_listener.orient.fvec.x, m_emulated_listener.orient.fvec.y,
m_emulated_listener.orient.fvec.z);
SSpListener_SetUpVector3f(m_lr, m_emulated_listener.orient.uvec.x, m_emulated_listener.orient.uvec.y,
m_emulated_listener.orient.uvec.z);
SSpListener_SetVelocity3f(m_lr, m_emulated_listener.velocity.x, m_emulated_listener.velocity.y,
m_emulated_listener.velocity.z);
}
#endif
}
// float ll_volume;
// Sets the master volume (2d and 3d sounds) -- chrishack -- use primary buffer
void mac_llsSystem::SetMasterVolume(float volume)
// void mac_llsSystem::SetLLVolume(float volume)
{
m_volume = volume;
}
// Gets the master volume
float mac_llsSystem::GetMasterVolume(void)
// float mac_llsSystem::GetLLVolume(void)
{
return m_volume; // ll_volume;
}
// Pause all sounds/resume all sounds
void mac_llsSystem::PauseSounds(void) {
int i;
SndCommand sndCommand;
OSErr err;
for (i = 0; i < m_channel_count; i++) {
if (snd_channel[i]->userInfo >= 0) {
sndCommand.cmd = pauseCmd;
sndCommand.param1 = 0;
sndCommand.param2 = 0L;
err = SndDoImmediate(snd_channel[i], &sndCommand);
if (err)
Error("Sound Channel %d is corrupt: pauseCmd", i);
}
}
}
void mac_llsSystem::ResumeSounds(void) {
int i;
SndCommand sndCommand;
OSErr err;
for (i = 0; i < m_channel_count; i++) {
if (snd_channel[i]->userInfo >= 0) {
sndCommand.cmd = resumeCmd;
sndCommand.param1 = 0;
sndCommand.param2 = 0L;
err = SndDoImmediate(snd_channel[i], &sndCommand);
if (err)
Error("Sound Channel %d is corrupt: resumeCmd", i);
}
}
}
// Begin sound frame
void mac_llsSystem::SoundStartFrame(void) {}
void mac_llsSystem::PauseSound(int sound_uid) {
int i;
SndCommand sndCommand;
OSErr err;
if (sound_uid < 0)
return;
for (i = 0; i < m_channel_count; i++) {
if (snd_channel[i]->userInfo == sound_uid) {
sndCommand.cmd = pauseCmd;
sndCommand.param1 = 0;
sndCommand.param2 = 0L;
err = SndDoImmediate(snd_channel[i], &sndCommand);
if (err)
Error("Sound Channel %d is corrupt: pauseCmd", i);
return;
}
}
}
void mac_llsSystem::ResumeSound(int sound_uid) {
int i;
SndCommand sndCommand;
OSErr err;
if (sound_uid < 0)
return;
for (i = 0; i < m_channel_count; i++) {
if (snd_channel[i]->userInfo == sound_uid) {
sndCommand.cmd = resumeCmd;
sndCommand.param1 = 0;
sndCommand.param2 = 0L;
err = SndDoImmediate(snd_channel[i], &sndCommand);
if (err)
Error("Sound Channel %d is corrupt: resumeCmd", i);
return;
}
}
}
bool mac_llsSystem::CheckAndForceSoundDataAlloc(int sound_uid) {
int result;
if (sound_uid < 0)
return;
int sound_file_index = Sounds[sound_uid].sample_index;
ASSERT(sound_file_index >= 0 && sound_file_index < MAX_SOUND_FILES);
if (sound_file_index < 0 || sound_file_index >= MAX_SOUND_FILES) {
return false;
}
// Check if the sample data is already loaded
if (SoundFiles[sound_file_index].sample_16bit != NULL || SoundFiles[sound_file_index].sample_8bit != NULL)
return true;
// If not, get the sound data
// result = SoundLoadWaveFile(SoundFiles[sound_file_index].name, Sounds[sound_uid].import_volume, sound_file_index,
//SQT_HIGH, true);
result = SoundLoadWaveFile(SoundFiles[sound_file_index].name, Sounds[sound_uid].import_volume, sound_file_index,
(m_sound_quality > 0) ? 1 : 0, true);
// Why would it load once (table load time) and not now?
if (!result)
return false;
// mprintf((1, "%s loaded.\n", SoundFiles[sound_file_index].name));
return true;
}
// End sound frame
void mac_llsSystem::SoundEndFrame(void) {}
ubyte mac_llsSystem::GetNumChannels(void) { return m_channel_count; }
int mac_llsSystem::FindFreeChannel(float volume, int priority) {
int i;
int found = -1;
int num_used_chan = 0;
float weighted_priority = priority * volume;
// first look for an empty slot
for (i = 0; i < m_channel_count; i++) {
if (snd_channel[i]->userInfo < 0) {
channel_priority[i] = weighted_priority;
return (i);
}
}
if (priority == 0) // lowest priority does not register past here
return -1;
// return the lowest priority slot
float min_priority = weighted_priority;
int min_chan = -1;
for (i = 0; i < m_channel_count; i++) {
if (channel_priority[i] < min_priority) {
min_priority = channel_priority[i];
min_chan = i;
}
}
if (min_chan != -1) {
// mprintf((1, "\nK %d snd %d pri %.5f > %.5f\n", min_chan, snd_channel[min_chan]->userInfo, weighted_priority,
//channel_priority[min_chan]));
StopSound(snd_channel[min_chan]->userInfo);
return (min_chan);
}
mprintf((2, "NO FREE Sound CHANNEL: priority %f\n", weighted_priority));
return -1;
}
void mac_llsSystem::SetNumChannels(ubyte num_chan) {
int i;
OSStatus err;
unsigned int cpuLoadLimit;
SoundComponentLink myLink;
SndCommand sndCommand;
if (!sndsprk_initialized)
return;
myLink.description.componentType = kSoundEffectsType;
myLink.description.componentSubType = kSSpLocalizationSubType;
myLink.description.componentManufacturer = kAnyComponentManufacturer;
myLink.description.componentFlags = 0;
myLink.description.componentFlagsMask = kAnyComponentFlagsMask;
myLink.mixerID = nil;
myLink.linkID = nil;
if (num_chan > m_channel_count) {
SndCallBackUPP myCallBackUPP;
myCallBackUPP = NewSndCallBackProc(SoundCallBack);
for (i = m_channel_count; i < num_chan; i++) {
snd_channel[i] = NULL;
err = SndNewChannel(&snd_channel[i], sampledSynth, initMono, myCallBackUPP);
if (err)
Error("Error %d Unable to allocate sound channel %d", err, i);
err = SndSetInfo(snd_channel[i], siPreMixerSoundComponent, &myLink);
if (err)
Error("SndSetInfo siPreMixerSoundComponent near Error %d", err);
err = SndSetInfo(snd_channel[i], siSSpLocalization, &snd_localization[SQT_LOW]);
if (err)
Error("unable to localize sound channel %d\n", i);
snd_channel[i]->userInfo = -1;
channel_priority[i] = 0;
}
} else if (num_chan < m_channel_count) {
for (i = m_channel_count - 1; i >= num_chan; i--) {
SndDisposeChannel(snd_channel[i], true);
snd_channel[i] = NULL;
}
}
m_channel_count = num_chan;
}
// environmental sound interface
// volume modifier (0-1), damping(0-1), 1 = complete, 0 = none
// decay 0.1 to 100 seconds, how long it takes for a sound to die.
bool mac_llsSystem::SetGlobalReverbProperties(float volume, float damping, float decay) {
#ifdef SPROCKET17
if (m_sound_quality == SQT_HIGH) {
SSpListener_SetReverb(m_lr, 9, damping * -20, volume * -20);
SSpListener_SetReverb(m_lr, 0, 0, 0);
}
#endif
return false;
}
// set special parameters for the 3d environment.
// of strcuture passed, you must set the appropriate 'flags' value for values you wish to modify
void mac_llsSystem::SetEnvironmentValues(const t3dEnvironmentValues *env) {}
// get special parameters for the 3d environment.
// of strcuture passed, you must set the appropriate 'flags' value for values you wish to modify
void mac_llsSystem::GetEnvironmentValues(t3dEnvironmentValues *env) {}
// enable special parameters for the 3d environment.
// of strcuture passed, you must set the appropriate 'flags' value for values you wish to modify
void mac_llsSystem::SetEnvironmentToggles(const t3dEnvironmentToggles *env) {}
// get states of special parameters for the 3d environment.
// of strcuture passed, you must set the appropriate 'flags' value for values you wish to modify
void mac_llsSystem::GetEnvironmentToggles(t3dEnvironmentToggles *env) {}
// Sound System Error Handler.
void mac_llsSystem::CheckForErrors() {
// if a fatal error occurred, quit and display an error
// non fatal errors should be put inside a logfile, or just mprinted out.
switch (m_lib_error_code) {}
// must call!
llsSystem::CheckForErrors();
}
short *sound_render_audible_rooms(pos_state *listener_pos, float max_radius) { return 0; };
void SoundRenderReset(){};
void sound_render_end_frame(){};
bool sound_render_start_frame() { return 0; };
/*
inline int mac_llsSystem::MakeUniqueId(int sound_index, int channel)
{
return (sound_index + (channel << 10));
}
inline int mac_llsSystem::DecodeId(int sound_index, int channel)
{
return (sound_index - (channel >> 10));
}
*/