Initial import of Red Planet v4.10 Win32 source
Imports the current Win32 source for the pod-racing game 'Red Planet', built on the MUNGA engine and its L4 (Win32/DirectX) platform layer: - MUNGA / MUNGA_L4: cross-platform engine core and Win32 backend - RP / RP_L4: Red Planet game logic and Win32 application - DivLoader, Setup1: asset loader and installer project - lib, MUNGA_L4/openal, MUNGA_L4/sos: third-party audio dependencies Removed stale Subversion metadata and added .gitignore/.gitattributes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,990 @@
|
||||
#include "mungal4.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "l4audhdw.h"
|
||||
|
||||
//#if defined(AUDIO_HARDWARE)
|
||||
// #include "sos\bc4\sosmawe.h"
|
||||
//#endif
|
||||
|
||||
#if defined(TRACE_AUDIO_RENDERER_MIDI)
|
||||
BitTrace Audio_Renderer_MIDI("Audio Renderer MIDI");
|
||||
#endif
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MPU Emulation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
#define _inp inportb
|
||||
#define _outp outportb
|
||||
|
||||
#define MPUPort(x) ((x)+mpuAddx)
|
||||
#define SBCPort(x) ((x)+srcAddx)
|
||||
|
||||
/* DSP defines */
|
||||
#define MPU_ACK_OK 0xfe
|
||||
#define MPU_RESET_CMD 0xff
|
||||
#define MPU_ENTER_UART 0x3f
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MIDIMessage ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// TestInstance
|
||||
//#############################################################################
|
||||
//
|
||||
Logical
|
||||
MIDIMessage::TestInstance() const
|
||||
{
|
||||
return True;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
std::ostream&
|
||||
operator << (
|
||||
std::ostream &strm,
|
||||
const MIDIMessage &midi_message
|
||||
)
|
||||
{
|
||||
Check(&midi_message);
|
||||
|
||||
strm << "[";
|
||||
strm << (int)(midi_message.message[0] & 0x0F) << ",";
|
||||
strm << (int)(midi_message.message[0] >> 4) << ",";
|
||||
strm << (int)midi_message.message[1] << ",";
|
||||
strm << (int)midi_message.message[2] << "]";
|
||||
|
||||
return strm;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioChannel ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
/*AudioChannel::AudioChannel(
|
||||
AudioChannelType audio_channel_type,
|
||||
MIDIChannel midi_channel,
|
||||
AudioCard *audio_card
|
||||
)
|
||||
{
|
||||
audioChannelType = audio_channel_type;
|
||||
midiChannel = midi_channel;
|
||||
voicesUsed = 0;
|
||||
Check(audio_card);
|
||||
audioCard = audio_card;
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
AudioChannel::~AudioChannel()
|
||||
{
|
||||
Verify(voicesUsed == 0);
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// TestInstance
|
||||
//#############################################################################
|
||||
//
|
||||
Logical
|
||||
AudioChannel::TestInstance() const
|
||||
{
|
||||
Plug::TestInstance();
|
||||
Verify(voicesUsed >=0 && voicesUsed <= AWE_VOICE_COUNT);
|
||||
Check(audioCard);
|
||||
return True;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioCard ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// AudioCard
|
||||
//#############################################################################
|
||||
//
|
||||
AudioCard::AudioCard():
|
||||
idleChannelSocket(NULL),
|
||||
percussionChannelSocket(NULL)
|
||||
{
|
||||
MIDIChannel channel;
|
||||
|
||||
idleVoices = AWE_VOICE_COUNT;
|
||||
for (channel = 0; channel < AWE_CHANNEL_COUNT; channel++)
|
||||
{
|
||||
AudioChannel *audio_channel;
|
||||
|
||||
if (channel == AWE_PERCUSSIVE_CHANNEL)
|
||||
{
|
||||
audio_channel =
|
||||
new AudioChannel(
|
||||
PercussionAudioChannelType,
|
||||
channel,
|
||||
this
|
||||
);
|
||||
Register_Object(audio_channel);
|
||||
Check(&percussionChannelSocket);
|
||||
percussionChannelSocket.Add(audio_channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
audio_channel =
|
||||
new AudioChannel(
|
||||
InstrumentAudioChannelType,
|
||||
channel,
|
||||
this
|
||||
);
|
||||
Register_Object(audio_channel);
|
||||
Check(&idleChannelSocket);
|
||||
idleChannelSocket.Add(audio_channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// ~AudioCard
|
||||
//#############################################################################
|
||||
//
|
||||
AudioCard::~AudioCard()
|
||||
{
|
||||
//
|
||||
// Delete the idle channels
|
||||
//
|
||||
{
|
||||
ChainIteratorOf<AudioChannel*> iterator(&idleChannelSocket);
|
||||
|
||||
Check(&iterator);
|
||||
Verify(idleVoices == AWE_VOICE_COUNT);
|
||||
Verify(iterator.GetSize() == AWE_CHANNEL_COUNT - 1);
|
||||
iterator.DeletePlugs();
|
||||
}
|
||||
|
||||
//
|
||||
// Delete the percussive channel
|
||||
//
|
||||
{
|
||||
ChainIteratorOf<AudioChannel*> iterator(&percussionChannelSocket);
|
||||
|
||||
Check(&iterator);
|
||||
Verify(idleVoices == AWE_VOICE_COUNT);
|
||||
Verify(iterator.GetSize() == 1);
|
||||
iterator.DeletePlugs();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// TestInstance
|
||||
//#############################################################################
|
||||
//
|
||||
Logical
|
||||
AudioCard::TestInstance() const
|
||||
{
|
||||
Node::TestInstance();
|
||||
Verify(idleVoices >= 0 && idleVoices <= AWE_VOICE_COUNT);
|
||||
Check(&idleChannelSocket);
|
||||
return True;
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// Initialize
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
AudioCard::Initialize()
|
||||
{
|
||||
#ifdef AUDIO_HARDWARE
|
||||
Tell("AudioCard::Initialize - Start\n");
|
||||
|
||||
WORD wError;
|
||||
|
||||
//
|
||||
// Set the selector of the pointer to the driver memory for the
|
||||
// MIDI driver to _NULL. this will tell the load driver routine
|
||||
// to allocate new memory for the MIDI driver
|
||||
//
|
||||
#if defined(__BCPLUSPLUS__)
|
||||
sSOSMIDIInitDriver.lpDriverMemory.sel = _NULL;
|
||||
#else
|
||||
sSOSMIDIInitDriver.lpDriverMemory = _NULL;
|
||||
#endif
|
||||
|
||||
//
|
||||
// Setup the port for the MIDI driver to use
|
||||
//
|
||||
// sSOSMIDIHardware.wPort = _MIDI_DRIVER_PORT;
|
||||
sSOSMIDIHardware.wPort = emuAddx;
|
||||
|
||||
//
|
||||
// Load and initialize the MIDI driver
|
||||
//
|
||||
wError = sosMIDIInitDriver(
|
||||
_MIDI_DRIVER_TYPE,
|
||||
&sSOSMIDIHardware,
|
||||
&sSOSMIDIInitDriver,
|
||||
&wDriverHandle
|
||||
);
|
||||
if (wError)
|
||||
{
|
||||
std::cout << sosGetErrorString(wError);
|
||||
Fail("AudioCard::Initialize - sosMIDIInitDriver failed\n");
|
||||
}
|
||||
|
||||
Tell("AudioCard::Initialize - Finish\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// Close
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
AudioCard::Close()
|
||||
{
|
||||
#ifdef AUDIO_HARDWARE
|
||||
Check(this);
|
||||
|
||||
sosMIDIAWE32ReleaseSBKFiles(wDriverHandle);
|
||||
|
||||
//
|
||||
// Reset the midi driver
|
||||
//
|
||||
sosMIDIResetDriver(wDriverHandle);
|
||||
|
||||
//
|
||||
// Uninitialize the midi driver and tell it to free the memory allocated
|
||||
// for the driver
|
||||
//
|
||||
sosMIDIUnInitDriver(wDriverHandle, _TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// GetEnvironmentSettings
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
AudioCard::GetEnvironmentSettings(char *env_str)
|
||||
{
|
||||
WORD src_addx = 0xffff;
|
||||
WORD irq_interrupt = 0xffff;
|
||||
WORD dma_channel = 0xffff;
|
||||
WORD mpu_addx = 0xffff;
|
||||
WORD emu_addx = 0xffff;
|
||||
|
||||
const char *sz_blaster;
|
||||
|
||||
sz_blaster = getenv(env_str);
|
||||
Check_Pointer(sz_blaster);
|
||||
|
||||
while (*sz_blaster) {
|
||||
if (*sz_blaster == 'a' || *sz_blaster == 'A') {
|
||||
++sz_blaster;
|
||||
if (*sz_blaster) {
|
||||
if (*sz_blaster == ':')
|
||||
++sz_blaster;
|
||||
src_addx = GetHexWord(&sz_blaster);
|
||||
}
|
||||
}
|
||||
if (*sz_blaster == 'i' || *sz_blaster == 'I') {
|
||||
++sz_blaster;
|
||||
if (*sz_blaster) {
|
||||
if (*sz_blaster == ':')
|
||||
++sz_blaster;
|
||||
irq_interrupt = GetHexWord(&sz_blaster);
|
||||
}
|
||||
}
|
||||
if (*sz_blaster == 'd' || *sz_blaster == 'D') {
|
||||
++sz_blaster;
|
||||
if (*sz_blaster) {
|
||||
if (*sz_blaster == ':')
|
||||
++sz_blaster;
|
||||
dma_channel = GetHexWord(&sz_blaster);
|
||||
}
|
||||
}
|
||||
if (*sz_blaster == 'e' || *sz_blaster == 'E') {
|
||||
++sz_blaster;
|
||||
if (*sz_blaster) {
|
||||
if (*sz_blaster == ':')
|
||||
++sz_blaster;
|
||||
emu_addx = GetHexWord(&sz_blaster);
|
||||
}
|
||||
}
|
||||
if (*sz_blaster == 'p' || *sz_blaster == 'P') {
|
||||
++sz_blaster;
|
||||
if (*sz_blaster) {
|
||||
if (*sz_blaster == ':')
|
||||
++sz_blaster;
|
||||
mpu_addx = GetHexWord(&sz_blaster);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Skip until blank or end of string
|
||||
//
|
||||
while (*sz_blaster && *sz_blaster != ' ')
|
||||
++sz_blaster;
|
||||
while (*sz_blaster == ' ')
|
||||
++sz_blaster;
|
||||
}
|
||||
|
||||
if (emu_addx == 0xffff)
|
||||
emu_addx = (WORD)(src_addx + 0x400);
|
||||
|
||||
srcAddx = src_addx;
|
||||
irqInterrupt = irq_interrupt;
|
||||
dmaChannel = dma_channel;
|
||||
mpuAddx = mpu_addx;
|
||||
emuAddx = emu_addx;
|
||||
|
||||
#if DEBUG_LEVEL>0
|
||||
Tell("AudioCard::GetEnvironmentSettings: " << env_str << "\n");
|
||||
#if 0
|
||||
Dump(srcAddx);
|
||||
Dump(irqInterrupt);
|
||||
Dump(dmaChannel);
|
||||
Dump(mpuAddx);
|
||||
Dump(emuAddx);
|
||||
#endif
|
||||
printf(" srcAddx = %x\n", (unsigned)srcAddx);
|
||||
printf(" irqInterrupt = %x\n", (unsigned)irqInterrupt);
|
||||
printf(" dmaChannel = %x\n", (unsigned)dmaChannel);
|
||||
printf(" mpuAddx = %x\n", (unsigned)mpuAddx);
|
||||
printf(" emuAddx = %x\n", (unsigned)emuAddx);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// InitMIDIReceive
|
||||
// Initializes Sound Blaster to ready to receive data state.
|
||||
//#############################################################################
|
||||
//
|
||||
Logical
|
||||
AudioCard::InitMIDIReceive()
|
||||
{
|
||||
#if 0
|
||||
volatile DWORD dwCount;
|
||||
|
||||
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
||||
dwCount = 0x2000;
|
||||
while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
|
||||
_outp(MPUPort(1), MPU_RESET_CMD);
|
||||
|
||||
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
||||
dwCount = 0x2000;
|
||||
while (dwCount && _inp(MPUPort(1)) & 0x80) --dwCount;
|
||||
_inp(MPUPort(0));
|
||||
|
||||
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
||||
dwCount = 0x2000;
|
||||
while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
|
||||
_outp(MPUPort(1), MPU_RESET_CMD);
|
||||
|
||||
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
||||
dwCount = 0x2000;
|
||||
while (dwCount && _inp(MPUPort(1)) & 0x80) --dwCount;
|
||||
_inp(MPUPort(0));
|
||||
|
||||
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
||||
dwCount = 0x2000;
|
||||
while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
|
||||
_outp(MPUPort(1), MPU_ENTER_UART);
|
||||
|
||||
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
||||
dwCount = 0x2000;
|
||||
while (dwCount && _inp(MPUPort(1)) & 0x80) --dwCount;
|
||||
if (!dwCount) return True;
|
||||
if (_inp(MPUPort(0)) != MPU_ACK_OK) return True;
|
||||
|
||||
// mask MPU-401 interrupt
|
||||
_outp(SBCPort(0x4), 0x83);
|
||||
_outp(SBCPort(0x5), _inp(SBCPort(0x5)) & ~0x04);
|
||||
#endif
|
||||
return False;
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// CloseMIDIReceive
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
AudioCard::CloseMIDIReceive()
|
||||
{
|
||||
#if 0
|
||||
volatile DWORD dwCount;
|
||||
|
||||
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
||||
dwCount = 0x2000;
|
||||
while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
|
||||
_outp(MPUPort(1), MPU_RESET_CMD);
|
||||
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
||||
_inp(MPUPort(0));
|
||||
|
||||
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
||||
dwCount = 0x2000;
|
||||
while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
|
||||
_outp(MPUPort(1), MPU_RESET_CMD);
|
||||
for (dwCount=0; dwCount<0x2000; dwCount++) ;
|
||||
_inp(MPUPort(0));
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// IsMIDIAvailable
|
||||
//#############################################################################
|
||||
//
|
||||
Logical
|
||||
AudioCard::IsMIDIAvailable()
|
||||
{
|
||||
#if 0
|
||||
return ((_inp(MPUPort(1)) & 0x80) == 0);
|
||||
#endif
|
||||
return False;
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// GetMIDIByte
|
||||
//#############################################################################
|
||||
//
|
||||
MIDIValue
|
||||
AudioCard::GetMIDIByte()
|
||||
{
|
||||
#if 0
|
||||
return (_inp(MPUPort(0)));
|
||||
#endif
|
||||
return (MIDIValue)0;
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// InitializeChannels
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
AudioCard::InitializeChannels()
|
||||
{
|
||||
Check(this);
|
||||
|
||||
//
|
||||
// Initialize idle channels
|
||||
//
|
||||
{
|
||||
ChainIteratorOf<AudioChannel*> iterator(&idleChannelSocket);
|
||||
AudioChannel *channel;
|
||||
|
||||
Check(&iterator);
|
||||
Verify(iterator.GetSize() == (AWE_CHANNEL_COUNT-1));
|
||||
while ((channel = iterator.ReadAndNext()) != NULL)
|
||||
{
|
||||
Check(channel);
|
||||
channel->SendPitchBendRange(MIDI_PITCH_BEND_RANGE);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize percussive channels
|
||||
//
|
||||
{
|
||||
ChainIteratorOf<AudioChannel*> iterator(&percussionChannelSocket);
|
||||
AudioChannel *channel;
|
||||
|
||||
Check(&iterator);
|
||||
Verify(iterator.GetSize() == 1);
|
||||
channel = iterator.GetCurrent();
|
||||
Check(channel);
|
||||
channel->SendPitchBendRange(MIDI_PITCH_BEND_RANGE);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// LoadSBK
|
||||
//#############################################################################
|
||||
//
|
||||
int
|
||||
AudioCard::LoadSBK(const char *file_name)
|
||||
{
|
||||
#ifdef AUDIO_HARDWARE
|
||||
Check(this);
|
||||
Check_Pointer(file_name);
|
||||
|
||||
int ret;
|
||||
|
||||
Tell("AudioCard::LoadSBK - " << file_name << "\n");
|
||||
ret = sosMIDIAWE32SetSBKFile(wDriverHandle, file_name);
|
||||
Verify_And_Dump(ret >= 0, ret);
|
||||
Tell("AudioCard::LoadSBK - Finished\n");
|
||||
return ret;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// ReleaseAllBanks
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
AudioCard::ReleaseAllBanks()
|
||||
{
|
||||
#ifdef AUDIO_HARDWARE
|
||||
Check(this);
|
||||
sosMIDIAWE32ReleaseSBKFiles(wDriverHandle);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// MIDI methods
|
||||
//#############################################################################
|
||||
//
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
AudioCard::SendPitchBend(
|
||||
MIDIChannel channel,
|
||||
MIDIPitchBend pitch_bend
|
||||
)
|
||||
{
|
||||
MIDIMessage
|
||||
message(
|
||||
MIDI_PITCH_BEND_STATUS,
|
||||
channel,
|
||||
(MIDIValue)((pitch_bend+8192)%128),
|
||||
(MIDIValue)((pitch_bend+8192)/128)
|
||||
);
|
||||
SendMIDIMessage(&message, 3);
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
AudioCard::SendPitchBendRange(
|
||||
MIDIChannel channel,
|
||||
MIDIValue sensitivity
|
||||
)
|
||||
{
|
||||
SendController(channel, (MIDIValue)101, (MIDIValue)0);
|
||||
SendController(channel, (MIDIValue)100, (MIDIValue)0);
|
||||
SendController(channel, (MIDIValue)6, sensitivity);
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
AudioCard::SendNRPN(
|
||||
MIDIChannel channel,
|
||||
MIDIValue param_number,
|
||||
MIDINRPNValue value
|
||||
)
|
||||
{
|
||||
//
|
||||
// Set sound parameter
|
||||
//
|
||||
SendController(channel, (MIDIValue)99, (MIDIValue)127);
|
||||
SendController(channel, (MIDIValue)98, param_number);
|
||||
|
||||
//
|
||||
// Set parameter value
|
||||
//
|
||||
SendController(channel, (MIDIValue)6, (MIDIValue)((value+8192)/128) );
|
||||
SendController(channel, (MIDIValue)38, (MIDIValue)((value+8192)%128) );
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
#define SYSEX_MACRO_LENGTH 11
|
||||
|
||||
Byte
|
||||
chorus_sysex[SYSEX_MACRO_LENGTH] =
|
||||
{
|
||||
0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x01, 0x38, 0x00, 0x00, 0xF7
|
||||
};
|
||||
|
||||
Byte
|
||||
reverb_sysex[SYSEX_MACRO_LENGTH] =
|
||||
{
|
||||
0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x01, 0x30, 0x00, 0x00, 0xF7
|
||||
};
|
||||
|
||||
void
|
||||
AudioCard::SelectEffect(
|
||||
MIDIEffectType type,
|
||||
MIDIValue effect
|
||||
)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ChorusMIDIEffectType:
|
||||
chorus_sysex[8] = effect;
|
||||
SendSysex(chorus_sysex, SYSEX_MACRO_LENGTH);
|
||||
break;
|
||||
|
||||
case ReverbMIDIEffectType:
|
||||
reverb_sysex[8] = effect;
|
||||
SendSysex(reverb_sysex, SYSEX_MACRO_LENGTH);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
AudioCard::SendSysex(
|
||||
void *data,
|
||||
size_t length
|
||||
)
|
||||
{
|
||||
#ifdef AUDIO_HARDWARE
|
||||
WORD wError;
|
||||
|
||||
//
|
||||
// Note - HMI can specify sysex channel via F0, F1, ..., FF
|
||||
//
|
||||
#if defined(__BCPLUSPLUS__)
|
||||
wError = sosMIDISendMIDIData(
|
||||
wDriverHandle,
|
||||
(char*)data,
|
||||
length
|
||||
);
|
||||
#else
|
||||
wError = sosMIDISendMIDIData(
|
||||
wDriverHandle,
|
||||
(Byte*)data,
|
||||
length
|
||||
);
|
||||
#endif
|
||||
if (wError != _ERR_NO_ERROR)
|
||||
{
|
||||
Fail("AudioCard::SendSysex - wError != _ERR_NO_ERROR");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
AudioCard::SendMIDIMessage(MIDIMessage *midi_message)
|
||||
{
|
||||
#ifdef AUDIO_HARDWARE
|
||||
SET_AUDIO_RENDERER_MIDI();
|
||||
|
||||
Check(midi_message);
|
||||
|
||||
#if 0
|
||||
long now = Now();
|
||||
Tell(now << "\t" << (int)srcAddx << "\t" << *midi_message << "\t");
|
||||
Tell(idleVoices << "\n");
|
||||
#endif
|
||||
|
||||
switch (midi_message->message[0] >> 4) {
|
||||
case MIDI_NOTE_ON_STATUS:
|
||||
case MIDI_NOTE_OFF_STATUS:
|
||||
case MIDI_POLYKEY_STATUS:
|
||||
case MIDI_CONTROLLER_STATUS:
|
||||
case MIDI_PITCH_BEND_STATUS:
|
||||
#if DEBUG_LEVEL>0
|
||||
{
|
||||
Word wError = sosMIDISendMIDIData(
|
||||
wDriverHandle,
|
||||
(char*)midi_message->message,
|
||||
3
|
||||
);
|
||||
Verify(wError == _ERR_NO_ERROR);
|
||||
}
|
||||
#else
|
||||
sosMIDISendMIDIData(
|
||||
wDriverHandle,
|
||||
(char*)midi_message->message,
|
||||
3
|
||||
);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case MIDI_PROGRAM_CHANGE_STATUS:
|
||||
case MIDI_CHANNEL_PRESSURE_STATUS:
|
||||
#if DEBUG_LEVEL>0
|
||||
{
|
||||
Word wError = sosMIDISendMIDIData(
|
||||
wDriverHandle,
|
||||
(char*)midi_message->message,
|
||||
2
|
||||
);
|
||||
Verify(wError == _ERR_NO_ERROR);
|
||||
}
|
||||
#else
|
||||
sosMIDISendMIDIData(
|
||||
wDriverHandle,
|
||||
(char*)midi_message->message,
|
||||
2
|
||||
);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
//
|
||||
// Should never reach here
|
||||
//
|
||||
Fail("Should never reach here");
|
||||
break;
|
||||
}
|
||||
CLEAR_AUDIO_RENDERER_MIDI();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// Channel methods
|
||||
//#############################################################################
|
||||
//
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
AudioChannel*
|
||||
AudioCard::RequestAudioChannel(AudioVoiceCount voice_count)
|
||||
{
|
||||
Check(this);
|
||||
|
||||
//
|
||||
// Monitor resource usage
|
||||
//
|
||||
#if 0
|
||||
#if DEBUG_LEVEL>0
|
||||
{
|
||||
ChainIteratorOf<AudioChannel*> iterator(&idleChannelSocket);
|
||||
|
||||
if (voice_count > idleVoices || iterator.GetSize() == 0)
|
||||
{
|
||||
Tell("RequestAudioChannel - voices: " << idleVoices);
|
||||
Tell(" channels: " << iterator.GetSize());
|
||||
Tell("\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// Are there enough voices to allocate
|
||||
//
|
||||
if (voice_count > idleVoices)
|
||||
return NULL;
|
||||
|
||||
//
|
||||
// Allocate a channel
|
||||
//
|
||||
ChainIteratorOf<AudioChannel*> iterator(&idleChannelSocket);
|
||||
AudioChannel *audio_channel;
|
||||
|
||||
Check(&iterator);
|
||||
if ((audio_channel = iterator.GetCurrent()) != NULL)
|
||||
{
|
||||
Check(audio_channel);
|
||||
iterator.Remove();
|
||||
idleVoices -= voice_count;
|
||||
audio_channel->SetVoicesUsed(voice_count);
|
||||
|
||||
return audio_channel;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
AudioCard::ReleaseAudioChannel(AudioChannel *audio_channel)
|
||||
{
|
||||
Check(this);
|
||||
Check(audio_channel);
|
||||
|
||||
#if 0
|
||||
Tell("AudioCard::ReleaseAudioChannel - Released channel\n");
|
||||
Tell(" ");
|
||||
Dump((int)audio_channel->GetChannelNumber());
|
||||
#endif
|
||||
|
||||
//
|
||||
// Add to idle list
|
||||
//
|
||||
idleVoices += audio_channel->GetVoicesUsed();
|
||||
Verify(idleVoices > 0 && idleVoices <= AWE_VOICE_COUNT);
|
||||
audio_channel->SetVoicesUsed(0);
|
||||
|
||||
idleChannelSocket.Add(audio_channel);
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// GetHexWord
|
||||
//#############################################################################
|
||||
//
|
||||
WORD
|
||||
AudioCard::GetHexWord(const char ** s)
|
||||
{
|
||||
WORD n = 0;
|
||||
|
||||
while (**s) {
|
||||
if (**s >= '0' && **s <= '9')
|
||||
n = (WORD)(n * 16 + (*(*s)++ - '0'));
|
||||
else
|
||||
if (**s >= 'a' && **s <= 'f')
|
||||
n = (WORD)(n * 16 + (*(*s)++ - 'a') + 10);
|
||||
else
|
||||
if (**s >= 'A' && **s <= 'F')
|
||||
n = (WORD)(n * 16 + (*(*s)++ - 'A') + 10);
|
||||
else
|
||||
break;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioHardware ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// AudioHardware
|
||||
//#############################################################################
|
||||
//
|
||||
AudioHardware::AudioHardware()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// ~AudioHardware
|
||||
//#############################################################################
|
||||
//
|
||||
AudioHardware::~AudioHardware()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// TestInstance
|
||||
//#############################################################################
|
||||
//
|
||||
Logical
|
||||
AudioHardware::TestInstance() const
|
||||
{
|
||||
Node::TestInstance();
|
||||
Check(&frontCard);
|
||||
Check(&rearCard);
|
||||
return True;
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// Initialize
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
AudioHardware::Initialize()
|
||||
{
|
||||
#ifdef AUDIO_HARDWARE
|
||||
Tell("AudioHardware::Initialize - Start\n");
|
||||
|
||||
#if 0
|
||||
//
|
||||
// initialize the TIMER system and tell it to call the DOS timer
|
||||
// at a rate of 19 times/second. the actual rate is 18.2, but
|
||||
// 19 is a good approximation.
|
||||
//
|
||||
if (getenv(TIMER_ENV) == NULL) // L4Time is not setting up timer
|
||||
{
|
||||
sosTIMERInitSystem(_TIMER_DOS_RATE, _SOS_DEBUG_NORMAL);
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// initialize the MIDI system
|
||||
//
|
||||
sosMIDIInitSystem((PSTR)_SOS_DRIVER_PATH, _SOS_DEBUG_NORMAL);
|
||||
|
||||
//
|
||||
// initialize the cards
|
||||
//
|
||||
frontCard.GetEnvironmentSettings(FRONT_CARD_ENV_VAR);
|
||||
rearCard.GetEnvironmentSettings(REAR_CARD_ENV_VAR);
|
||||
frontCard.Initialize();
|
||||
rearCard.Initialize();
|
||||
|
||||
//
|
||||
// Setup standard channel attributes
|
||||
//
|
||||
frontCard.InitializeChannels();
|
||||
rearCard.InitializeChannels();
|
||||
|
||||
Tell("AudioHardware::Initialize - Finish\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// Close
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
AudioHardware::Close()
|
||||
{
|
||||
#ifdef AUDIO_HARDWARE
|
||||
Check(this);
|
||||
|
||||
//
|
||||
// Close the cards
|
||||
//
|
||||
frontCard.Close();
|
||||
rearCard.Close();
|
||||
|
||||
#if 0
|
||||
//
|
||||
// Uninitialize the TIMER system and pass it the value to write to the
|
||||
// timer chip to reset the timer, 0 is equivalent to 18.2 times/second
|
||||
// which is the DOS clock rate. the calculation for the value to pass
|
||||
// is 1193180/RATE.
|
||||
//
|
||||
if (getenv(TIMER_ENV) == NULL) // L4Time is not setting up timer
|
||||
{
|
||||
sosTIMERUnInitSystem(0);
|
||||
}
|
||||
sosTIMERUnInitSystem(0);
|
||||
#endif
|
||||
|
||||
//
|
||||
// Uninitialize the MIDI system
|
||||
//
|
||||
sosMIDIUnInitSystem();
|
||||
#endif
|
||||
}*/
|
||||
|
||||
#ifdef TEST_CLASS
|
||||
# include "l4audhdw.tcp"
|
||||
#endif
|
||||
Reference in New Issue
Block a user