Archival snapshot of the Virtual World Entertainment Tesla cockpit software, 1994-1996: MUNGA engine and L4 pod layer source (Borland C++ 5.0), BT/RP game code, and game content (models, audio, maps, gauges, Division renderer data). Includes third-party libraries: Division dVS/DPL graphics, HMI SOS audio, WATTCP networking. Files are preserved byte-for-byte (.gitattributes disables all line-ending conversion). README.md documents the layout, target hardware, and toolchain. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
822 lines
18 KiB
C++
822 lines
18 KiB
C++
//===========================================================================//
|
|
// File: l4audhdw.hh //
|
|
// Project: MUNGA Brick: Audio Manager //
|
|
// Contents: Spec for audio manager //
|
|
//---------------------------------------------------------------------------//
|
|
// Date Who Modification //
|
|
// -------- --- ---------------------------------------------------------- //
|
|
// 01/25/95 ECH Initial coding. //
|
|
//---------------------------------------------------------------------------//
|
|
// Copyright (C) 1994, Virtual World Entertainment, Inc. //
|
|
// All Rights reserved worldwide //
|
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
|
//===========================================================================//
|
|
|
|
#if !defined(L4AUDHDW_HPP)
|
|
# define L4AUDHDW_HPP
|
|
|
|
# define AUDIO_HARDWARE
|
|
|
|
# if !defined(STYLE_HPP)
|
|
# include <style.hpp>
|
|
# endif
|
|
|
|
# ifdef AUDIO_HARDWARE
|
|
# ifndef _SOS_MIDI_DEFINED
|
|
# include <sosm.h>
|
|
# endif
|
|
# else
|
|
typedef Byte BYTE;
|
|
typedef Word WORD;
|
|
# endif
|
|
|
|
# if !defined(NODE_HPP)
|
|
# include <node.hpp>
|
|
# endif
|
|
|
|
# if !defined(SCHAIN_HPP)
|
|
# include <schain.hpp>
|
|
# endif
|
|
|
|
# if !defined(AUDIO_HPP)
|
|
# include <audio.hpp>
|
|
# endif
|
|
|
|
#if defined(TRACE_AUDIO_RENDERER_MIDI)
|
|
extern BitTrace Audio_Renderer_MIDI("Audio Renderer MIDI");
|
|
#define SET_AUDIO_RENDERER_MIDI() Audio_Renderer_MIDI.Set()
|
|
#define CLEAR_AUDIO_RENDERER_MIDI() Audio_Renderer_MIDI.Clear()
|
|
#else
|
|
#define SET_AUDIO_RENDERER_MIDI()
|
|
#define CLEAR_AUDIO_RENDERER_MIDI()
|
|
#endif
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MIDI types ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
typedef unsigned char MIDIStatus;
|
|
typedef unsigned char MIDIChannel;
|
|
typedef unsigned char MIDIValue;
|
|
typedef int MIDIPitchBend;
|
|
typedef int MIDINRPNValue;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MIDI status ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
#define MIDI_CHANNEL_COUNT (16)
|
|
|
|
#define MIDI_NOTE_OFF_STATUS ((MIDIValue)0x8) // 8
|
|
#define MIDI_NOTE_ON_STATUS ((MIDIValue)0x9) // 9
|
|
#define MIDI_POLYKEY_STATUS ((MIDIValue)0xa) // 10
|
|
#define MIDI_CONTROLLER_STATUS ((MIDIValue)0xb) // 11
|
|
#define MIDI_PROGRAM_CHANGE_STATUS ((MIDIValue)0xc) // 12
|
|
#define MIDI_CHANNEL_PRESSURE_STATUS ((MIDIValue)0xd) // 13
|
|
#define MIDI_PITCH_BEND_STATUS ((MIDIValue)0xe) // 14
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~ MIDI controllers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
#define MIDI_MAX_CONTROL_VALUE ((MIDIValue)127)
|
|
#define MIDI_MIN_CONTROL_VALUE ((MIDIValue)0)
|
|
|
|
#define MIDI_LEFT_PAN_VALUE ((MIDIValue)0)
|
|
#define MIDI_CENTER_PAN_VALUE ((MIDIValue)63)
|
|
#define MIDI_RIGHT_PAN_VALUE ((MIDIValue)127)
|
|
|
|
#define MIDI_VOLUME_CONTROL ((MIDIValue)7)
|
|
#define MIDI_PAN_CONTROL ((MIDIValue)10)
|
|
#define MIDI_REVERB_CONTROL ((MIDIValue)91)
|
|
#define MIDI_CHORUS_CONTROL ((MIDIValue)93)
|
|
#define MIDI_CONTROL_RESET ((MIDIValue)121)
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MIDI notes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
#define MIDI_DEFAULT_NOTE ((MIDIValue)60)
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MIDI pitch ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
#define MIDI_PITCH_BEND_MAX ((MIDIPitchBend)8191)
|
|
#define MIDI_PITCH_BEND_RANGE ((MIDIValue)24)
|
|
#define MIDI_PITCH_BEND_CENTS (24*100)
|
|
#define MIDI_PITCH_PER_CENTS ((Scalar)MIDI_PITCH_BEND_MAX / \
|
|
(Scalar)MIDI_PITCH_BEND_CENTS)
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AWE NRPN ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
#define AWE_VOL_ATTACK_TIME_NRPN ((MIDIValue)11)
|
|
#define AWE_PITCH_NRPN ((MIDIValue)16)
|
|
#define AWE_FILTER_CUTOFF_NRPN ((MIDIValue)21)
|
|
|
|
#define AWE_VOL_ATTACK_TIME_RANGE ((MIDINRPNValue)5940) // 0...5.9 secs
|
|
#define AWE_FILTER_CUTOFF_RANGE ((MIDINRPNValue)127) // 100...8000 Hz
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AWE effects ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
typedef enum {
|
|
ChorusMIDIEffectType,
|
|
ReverbMIDIEffectType
|
|
} MIDIEffectType;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~ AWE resources ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
#define AWE_VOICE_COUNT (32)
|
|
#define AWE_CHANNEL_COUNT (16)
|
|
#define AWE_PERCUSSIVE_CHANNEL (9)
|
|
|
|
//
|
|
// Driver type to use
|
|
//
|
|
#define _MIDI_DRIVER_TYPE _MIDI_AWE32
|
|
|
|
//
|
|
// Path to the driver file
|
|
//
|
|
#define _SOS_DRIVER_PATH _NULL
|
|
|
|
//
|
|
// AWE environment variables
|
|
//
|
|
#define FRONT_CARD_ENV_VAR "AWE_FRONT"
|
|
#define REAR_CARD_ENV_VAR "AWE_REAR"
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MIDIMessage ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
#define MIDI_MESSAGE_SIZE (3)
|
|
|
|
class MIDIMessage SIGNATURED
|
|
{
|
|
friend class AudioCard;
|
|
friend ostream&
|
|
operator << (
|
|
ostream &strm,
|
|
const MIDIMessage &midi_message
|
|
);
|
|
|
|
public:
|
|
MIDIMessage(
|
|
MIDIStatus status,
|
|
MIDIChannel channel,
|
|
MIDIValue byte1,
|
|
MIDIValue byte2 = 0
|
|
);
|
|
~MIDIMessage() {}
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
|
|
private:
|
|
MIDIValue
|
|
message[MIDI_MESSAGE_SIZE];
|
|
};
|
|
|
|
inline MIDIMessage::MIDIMessage(
|
|
MIDIStatus status,
|
|
MIDIChannel channel,
|
|
MIDIValue byte1,
|
|
MIDIValue byte2
|
|
)
|
|
{
|
|
message[0] = (MIDIValue)((status << 4) | channel);
|
|
message[1] = byte1;
|
|
message[2] = byte2;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioChannel ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
typedef enum
|
|
{
|
|
InstrumentAudioChannelType = 0,
|
|
PercussionAudioChannelType
|
|
} AudioChannelType;
|
|
|
|
class AudioCard;
|
|
|
|
class AudioChannel:
|
|
public Plug
|
|
{
|
|
public:
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Constructor, Destructor, Testing
|
|
//--------------------------------------------------------------------
|
|
//
|
|
AudioChannel(
|
|
AudioChannelType audio_channel_type,
|
|
MIDIChannel midi_channel,
|
|
AudioCard *audio_card
|
|
);
|
|
~AudioChannel();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Accessors
|
|
//--------------------------------------------------------------------
|
|
//
|
|
AudioChannelType
|
|
GetAudioChannelType()
|
|
{return audioChannelType;}
|
|
MIDIChannel
|
|
GetChannelNumber()
|
|
{return midiChannel;}
|
|
void
|
|
SetVoicesUsed(AudioVoiceCount voices_used)
|
|
{voicesUsed = voices_used;}
|
|
AudioVoiceCount
|
|
GetVoicesUsed()
|
|
{return voicesUsed;}
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// MIDI methods
|
|
//--------------------------------------------------------------------
|
|
//
|
|
void
|
|
SendNoteOn(
|
|
MIDIValue key,
|
|
MIDIValue velocity
|
|
);
|
|
void
|
|
SendNoteOff(
|
|
MIDIValue key,
|
|
MIDIValue velocity
|
|
);
|
|
void
|
|
SendProgramChange(
|
|
MIDIValue program
|
|
);
|
|
void
|
|
SendController(
|
|
MIDIValue controller,
|
|
MIDIValue value
|
|
);
|
|
void
|
|
SendPolyKeyPressure(
|
|
MIDIValue key,
|
|
MIDIValue value
|
|
);
|
|
void
|
|
SendChannelPressure(
|
|
MIDIValue value
|
|
);
|
|
void
|
|
SendPitchBend(
|
|
MIDIPitchBend pitch_bend
|
|
);
|
|
void
|
|
SendPitchBendRange(
|
|
MIDIValue sensitivity
|
|
);
|
|
void
|
|
SendNRPN(
|
|
MIDIValue paramNumber,
|
|
MIDINRPNValue value
|
|
);
|
|
void
|
|
SelectEffect(
|
|
MIDIEffectType type,
|
|
MIDIValue effect
|
|
);
|
|
void
|
|
SelectBank(
|
|
MIDIValue bank
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Release
|
|
//--------------------------------------------------------------------
|
|
//
|
|
void
|
|
Release();
|
|
|
|
private:
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Private data
|
|
//--------------------------------------------------------------------
|
|
//
|
|
AudioChannelType
|
|
audioChannelType;
|
|
MIDIChannel
|
|
midiChannel;
|
|
AudioVoiceCount
|
|
voicesUsed;
|
|
AudioCard
|
|
*audioCard;
|
|
};
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioCard ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
class AudioCard:
|
|
public Node
|
|
{
|
|
friend class AudioHardware;
|
|
|
|
public:
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Constructor, Destructor, Testing
|
|
//--------------------------------------------------------------------
|
|
//
|
|
AudioCard();
|
|
~AudioCard();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Public methods
|
|
//--------------------------------------------------------------------
|
|
//
|
|
void
|
|
Initialize();
|
|
void
|
|
Close();
|
|
void
|
|
GetEnvironmentSettings(char *env_str);
|
|
|
|
Logical
|
|
InitMIDIReceive();
|
|
void
|
|
CloseMIDIReceive();
|
|
Logical
|
|
IsMIDIAvailable();
|
|
MIDIValue
|
|
GetMIDIByte();
|
|
|
|
void
|
|
InitializeChannels();
|
|
int
|
|
LoadSBK(const char *file_name);
|
|
void
|
|
ReleaseAllBanks();
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// MIDI methods
|
|
//--------------------------------------------------------------------
|
|
//
|
|
void
|
|
SendNoteOn(
|
|
MIDIChannel channel,
|
|
MIDIValue key,
|
|
MIDIValue velocity
|
|
);
|
|
void
|
|
SendNoteOff(
|
|
MIDIChannel channel,
|
|
MIDIValue key,
|
|
MIDIValue velocity
|
|
);
|
|
void
|
|
SendProgramChange(
|
|
MIDIChannel channel,
|
|
MIDIValue program
|
|
);
|
|
void
|
|
SendController(
|
|
MIDIChannel channel,
|
|
MIDIValue controller,
|
|
MIDIValue value
|
|
);
|
|
void
|
|
SendPolyKeyPressure(
|
|
MIDIChannel channel,
|
|
MIDIValue key,
|
|
MIDIValue value
|
|
);
|
|
void
|
|
SendChannelPressure(
|
|
MIDIChannel channel,
|
|
MIDIValue value
|
|
);
|
|
void
|
|
SendPitchBendRange(
|
|
MIDIChannel channel,
|
|
MIDIValue sensitivity
|
|
);
|
|
void
|
|
SendPitchBend(
|
|
MIDIChannel channel,
|
|
MIDIPitchBend pitch_bend
|
|
);
|
|
void
|
|
SendSysex(
|
|
void *data,
|
|
size_t length
|
|
);
|
|
void
|
|
SendNRPN(
|
|
MIDIChannel channel,
|
|
MIDIValue paramNumber,
|
|
MIDINRPNValue value
|
|
);
|
|
void
|
|
SelectEffect(
|
|
MIDIEffectType type,
|
|
MIDIValue effect
|
|
);
|
|
void
|
|
SelectBank(
|
|
MIDIChannel channel,
|
|
MIDIValue bank
|
|
);
|
|
void
|
|
SendMIDIMessage(
|
|
MIDIMessage *midi_message,
|
|
Word length
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Channel methods
|
|
//--------------------------------------------------------------------
|
|
//
|
|
AudioChannel*
|
|
RequestAudioChannel(AudioVoiceCount voice_count);
|
|
void
|
|
ReleaseAudioChannel(AudioChannel *audio_channel);
|
|
|
|
private:
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Private methods
|
|
//--------------------------------------------------------------------
|
|
//
|
|
WORD
|
|
GetHexWord(const char ** s);
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Private data
|
|
//--------------------------------------------------------------------
|
|
//
|
|
|
|
//
|
|
// Card addresses
|
|
//
|
|
WORD srcAddx;
|
|
WORD irqInterrupt;
|
|
WORD dmaChannel;
|
|
WORD mpuAddx;
|
|
WORD emuAddx;
|
|
|
|
//
|
|
// Structure for the MIDI driver initialization function
|
|
// Structure for the MIDI driver hardware
|
|
//
|
|
#ifdef AUDIO_HARDWARE
|
|
_SOS_MIDI_INIT_DRIVER sSOSMIDIInitDriver;
|
|
_SOS_MIDI_HARDWARE sSOSMIDIHardware;
|
|
#endif
|
|
|
|
//
|
|
// Handle for the loaded MIDI driver
|
|
//
|
|
WORD wDriverHandle;
|
|
|
|
//
|
|
// Number of free voices
|
|
//
|
|
AudioVoiceCount
|
|
idleVoices;
|
|
|
|
//
|
|
// Idle channels
|
|
//
|
|
ChainOf<AudioChannel*>
|
|
idleChannelSocket;
|
|
ChainOf<AudioChannel*>
|
|
percussionChannelSocket;
|
|
};
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioHardware ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
class AudioHardware:
|
|
public Node
|
|
{
|
|
public:
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Constructor, Destructor, Testing
|
|
//--------------------------------------------------------------------
|
|
//
|
|
AudioHardware();
|
|
~AudioHardware();
|
|
|
|
Logical
|
|
TestInstance() const;
|
|
static Logical
|
|
TestClass();
|
|
static Logical
|
|
ProfileClass();
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Public methods
|
|
//--------------------------------------------------------------------
|
|
//
|
|
void
|
|
Initialize();
|
|
void
|
|
Close();
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Card Access
|
|
//--------------------------------------------------------------------
|
|
//
|
|
AudioCard*
|
|
GetFrontCard();
|
|
|
|
AudioCard*
|
|
GetRearCard();
|
|
|
|
private:
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Private methods
|
|
//--------------------------------------------------------------------
|
|
//
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// Private data
|
|
//--------------------------------------------------------------------
|
|
//
|
|
AudioCard
|
|
frontCard;
|
|
AudioCard
|
|
rearCard;
|
|
};
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioCard inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
inline void
|
|
AudioCard::SendMIDIMessage(
|
|
MIDIMessage *midi_message,
|
|
Word length
|
|
)
|
|
{
|
|
#ifdef AUDIO_HARDWARE
|
|
SET_AUDIO_RENDERER_MIDI();
|
|
|
|
Check_Signature(midi_message);
|
|
#if DEBUG_LEVEL>0
|
|
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:
|
|
Verify(length == 3);
|
|
break;
|
|
|
|
case MIDI_PROGRAM_CHANGE_STATUS:
|
|
case MIDI_CHANNEL_PRESSURE_STATUS:
|
|
Verify(length == 2);
|
|
break;
|
|
default:
|
|
Fail("Should never reach here");
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
#if DEBUG_LEVEL>0
|
|
{
|
|
Word wError = sosMIDISendMIDIData(
|
|
wDriverHandle,
|
|
(char*)midi_message->message,
|
|
length
|
|
);
|
|
Verify(wError == _ERR_NO_ERROR);
|
|
}
|
|
#else
|
|
sosMIDISendMIDIData(
|
|
wDriverHandle,
|
|
(char*)midi_message->message,
|
|
length
|
|
);
|
|
#endif
|
|
CLEAR_AUDIO_RENDERER_MIDI();
|
|
#endif
|
|
}
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// MIDI methods
|
|
//--------------------------------------------------------------------
|
|
//
|
|
inline void
|
|
AudioCard::SendNoteOn(
|
|
MIDIChannel channel,
|
|
MIDIValue key,
|
|
MIDIValue velocity
|
|
)
|
|
{
|
|
MIDIMessage message(MIDI_NOTE_ON_STATUS, channel, key, velocity);
|
|
SendMIDIMessage(&message, 3);
|
|
}
|
|
|
|
inline void
|
|
AudioCard::SendNoteOff(
|
|
MIDIChannel channel,
|
|
MIDIValue key,
|
|
MIDIValue velocity
|
|
)
|
|
{
|
|
MIDIMessage message(MIDI_NOTE_OFF_STATUS, channel, key, velocity);
|
|
SendMIDIMessage(&message, 3);
|
|
}
|
|
|
|
inline void
|
|
AudioCard::SendProgramChange(
|
|
MIDIChannel channel,
|
|
MIDIValue program
|
|
)
|
|
{
|
|
MIDIMessage message(MIDI_PROGRAM_CHANGE_STATUS, channel, program);
|
|
SendMIDIMessage(&message, 2);
|
|
}
|
|
|
|
inline void
|
|
AudioCard::SendController(
|
|
MIDIChannel channel,
|
|
MIDIValue controller,
|
|
MIDIValue value
|
|
)
|
|
{
|
|
MIDIMessage message(MIDI_CONTROLLER_STATUS, channel, controller, value);
|
|
SendMIDIMessage(&message, 3);
|
|
}
|
|
|
|
inline void
|
|
AudioCard::SendPolyKeyPressure(
|
|
MIDIChannel channel,
|
|
MIDIValue key,
|
|
MIDIValue value
|
|
)
|
|
{
|
|
MIDIMessage message(MIDI_POLYKEY_STATUS, channel, key, value);
|
|
SendMIDIMessage(&message, 3);
|
|
}
|
|
|
|
inline void
|
|
AudioCard::SendChannelPressure(
|
|
MIDIChannel channel,
|
|
MIDIValue value
|
|
)
|
|
{
|
|
MIDIMessage message(MIDI_CHANNEL_PRESSURE_STATUS, channel, value);
|
|
SendMIDIMessage(&message, 2);
|
|
}
|
|
|
|
inline void
|
|
AudioCard::SelectBank(
|
|
MIDIChannel channel,
|
|
MIDIValue bank
|
|
)
|
|
{
|
|
SendController(channel, (MIDIValue)0, bank);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioChannel inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// MIDI methods
|
|
//--------------------------------------------------------------------
|
|
//
|
|
inline void
|
|
AudioChannel::SendNoteOn(
|
|
MIDIValue key,
|
|
MIDIValue velocity
|
|
)
|
|
{
|
|
Check(audioCard);
|
|
audioCard->SendNoteOn(midiChannel,key,velocity);
|
|
}
|
|
|
|
inline void
|
|
AudioChannel::SendNoteOff(
|
|
MIDIValue key,
|
|
MIDIValue velocity
|
|
)
|
|
{
|
|
Check(audioCard);
|
|
audioCard->SendNoteOff(midiChannel,key,velocity);
|
|
}
|
|
|
|
inline void
|
|
AudioChannel::SendProgramChange(
|
|
MIDIValue program
|
|
)
|
|
{
|
|
Check(audioCard);
|
|
audioCard->SendProgramChange(midiChannel,program);
|
|
}
|
|
|
|
inline void
|
|
AudioChannel::SendController(
|
|
MIDIValue controller,
|
|
MIDIValue value
|
|
)
|
|
{
|
|
Check(audioCard);
|
|
audioCard->SendController(midiChannel,controller,value);
|
|
}
|
|
|
|
inline void
|
|
AudioChannel::SendPolyKeyPressure(
|
|
MIDIValue key,
|
|
MIDIValue value
|
|
)
|
|
{
|
|
Check(audioCard);
|
|
audioCard->SendPolyKeyPressure(midiChannel,key,value);
|
|
}
|
|
|
|
inline void
|
|
AudioChannel::SendChannelPressure(
|
|
MIDIValue value
|
|
)
|
|
{
|
|
Check(audioCard);
|
|
audioCard->SendChannelPressure(midiChannel,value);
|
|
}
|
|
|
|
inline void
|
|
AudioChannel::SendPitchBend(
|
|
MIDIPitchBend pitch_bend
|
|
)
|
|
{
|
|
Check(audioCard);
|
|
audioCard->SendPitchBend(midiChannel,pitch_bend);
|
|
}
|
|
|
|
inline void
|
|
AudioChannel::SendPitchBendRange(
|
|
MIDIValue sensitivity
|
|
)
|
|
{
|
|
Check(audioCard);
|
|
audioCard->SendPitchBendRange(midiChannel,sensitivity);
|
|
}
|
|
|
|
inline void
|
|
AudioChannel::SelectEffect(
|
|
MIDIEffectType type,
|
|
MIDIValue effect
|
|
)
|
|
{
|
|
Check(audioCard);
|
|
audioCard->SelectEffect(type,effect);
|
|
}
|
|
|
|
inline void
|
|
AudioChannel::SendNRPN(
|
|
MIDIValue paramNumber,
|
|
MIDINRPNValue value
|
|
)
|
|
{
|
|
Check(audioCard);
|
|
audioCard->SendNRPN(midiChannel,paramNumber,value);
|
|
}
|
|
|
|
inline void
|
|
AudioChannel::SelectBank(
|
|
MIDIValue bank
|
|
)
|
|
{
|
|
Check(audioCard);
|
|
audioCard->SelectBank(midiChannel,bank);
|
|
}
|
|
|
|
inline void
|
|
AudioChannel::Release()
|
|
{
|
|
Check(audioCard);
|
|
audioCard->ReleaseAudioChannel(this);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~ AudioHardware inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
inline AudioCard*
|
|
AudioHardware::GetFrontCard()
|
|
{
|
|
Check(this);
|
|
return &frontCard;
|
|
}
|
|
|
|
inline AudioCard*
|
|
AudioHardware::GetRearCard()
|
|
{
|
|
Check(this);
|
|
return &rearCard;
|
|
}
|
|
|
|
#endif
|
|
|