Added support for DMX and MSOPL true stereo extension.
parent
597a342838
commit
03e7b666ae
|
@ -149,6 +149,8 @@ static OSType getOSType(const char * in_)
|
|||
msplayer->set_synth(0);
|
||||
|
||||
msplayer->set_bank([[plugin substringFromIndex:4] intValue]);
|
||||
|
||||
msplayer->set_extp(1);
|
||||
|
||||
msplayer->setSampleRate( 44100 );
|
||||
}
|
||||
|
@ -160,7 +162,9 @@ static OSType getOSType(const char * in_)
|
|||
msplayer->set_synth(1);
|
||||
|
||||
msplayer->set_bank([[plugin substringFromIndex:5] intValue]);
|
||||
|
||||
|
||||
msplayer->set_extp(1);
|
||||
|
||||
msplayer->setSampleRate( 44100 );
|
||||
}
|
||||
else
|
||||
|
@ -318,6 +322,11 @@ static OSType getOSType(const char * in_)
|
|||
player = NULL;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self close];
|
||||
}
|
||||
|
||||
+ (NSArray *)fileTypes
|
||||
{
|
||||
return [NSArray arrayWithObjects:@"mid", @"midi", @"kar", @"rmi", @"mids", @"mds", @"hmi", @"hmp", @"mus", @"xmi", @"lds", nil];
|
||||
|
|
|
@ -25,6 +25,12 @@ void MSPlayer::set_bank(unsigned int bank_id)
|
|||
this->bank_id = bank_id;
|
||||
}
|
||||
|
||||
void MSPlayer::set_extp(unsigned int extp)
|
||||
{
|
||||
shutdown();
|
||||
this->extp = extp;
|
||||
}
|
||||
|
||||
void MSPlayer::send_event(uint32_t b)
|
||||
{
|
||||
if (!(b & 0x80000000))
|
||||
|
@ -74,7 +80,7 @@ bool MSPlayer::startup()
|
|||
|
||||
if (!synth) return false;
|
||||
|
||||
if (!synth->midi_init((unsigned int)uSampleRate, bank_id))
|
||||
if (!synth->midi_init((unsigned int)uSampleRate, bank_id, extp))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
|
@ -18,6 +18,7 @@ public:
|
|||
|
||||
void set_synth(unsigned int synth);
|
||||
void set_bank(unsigned int bank);
|
||||
void set_extp(unsigned int extp);
|
||||
|
||||
typedef void (*enum_callback)(unsigned int synth, unsigned int bank, const char * name);
|
||||
|
||||
|
@ -33,6 +34,7 @@ protected:
|
|||
private:
|
||||
unsigned int synth_id;
|
||||
unsigned int bank_id;
|
||||
unsigned int extp;
|
||||
midisynth * synth;
|
||||
};
|
||||
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
#include <string.h>
|
||||
#include "opl3.h"
|
||||
|
||||
// Extended panning mode
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
|
||||
#define RSM_FRAC 10
|
||||
|
||||
// Channel types
|
||||
|
@ -933,7 +937,10 @@ static void OPL3_ChannelWriteC0(opl3_channel *channel, Bit8u data)
|
|||
{
|
||||
OPL3_ChannelSetupAlg(channel);
|
||||
}
|
||||
if (channel->chip->newm)
|
||||
if (channel->chip->extp)
|
||||
{
|
||||
}
|
||||
else if (channel->chip->newm)
|
||||
{
|
||||
channel->cha = ((data >> 4) & 0x01) ? ~0 : 0;
|
||||
channel->chb = ((data >> 5) & 0x01) ? ~0 : 0;
|
||||
|
@ -1120,6 +1127,17 @@ void OPL3_Generate(opl3_chip *chip, Bit16s *buf)
|
|||
}
|
||||
|
||||
chip->mixbuff[0] = 0;
|
||||
if (chip->extp)
|
||||
for (ii = 0; ii < 18; ii++)
|
||||
{
|
||||
accm = 0;
|
||||
for (jj = 0; jj < 4; jj++)
|
||||
{
|
||||
accm += *chip->channel[ii].out[jj];
|
||||
}
|
||||
chip->mixbuff[0] += (Bit16s)(accm * chip->channel[ii].cha / 65535);
|
||||
}
|
||||
else
|
||||
for (ii = 0; ii < 18; ii++)
|
||||
{
|
||||
accm = 0;
|
||||
|
@ -1159,6 +1177,17 @@ void OPL3_Generate(opl3_chip *chip, Bit16s *buf)
|
|||
}
|
||||
|
||||
chip->mixbuff[1] = 0;
|
||||
if (chip->extp)
|
||||
for (ii = 0; ii < 18; ii++)
|
||||
{
|
||||
accm = 0;
|
||||
for (jj = 0; jj < 4; jj++)
|
||||
{
|
||||
accm += *chip->channel[ii].out[jj];
|
||||
}
|
||||
chip->mixbuff[1] += (Bit16s)(accm * chip->channel[ii].chb / 65535);
|
||||
}
|
||||
else
|
||||
for (ii = 0; ii < 18; ii++)
|
||||
{
|
||||
accm = 0;
|
||||
|
@ -1276,6 +1305,21 @@ void OPL3_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v)
|
|||
case 0x05:
|
||||
chip->newm = v & 0x01;
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
chip->extp = v == 0x17;
|
||||
break;
|
||||
case 0x07:
|
||||
if (chip->extp)
|
||||
chip->panch = v;
|
||||
break;
|
||||
case 0x08:
|
||||
if (chip->extp && chip->panch < 18)
|
||||
{
|
||||
chip->channel[chip->panch].cha = (Bit16u)(cos((float)v * (M_PI / 2.0f / 255.0f)) * 65535.0f);
|
||||
chip->channel[chip->panch].chb = (Bit16u)(sin((float)v * (M_PI / 2.0f / 255.0f)) * 65535.0f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -89,6 +89,8 @@ struct _opl3_chip {
|
|||
opl3_slot slot[36];
|
||||
Bit16u timer;
|
||||
Bit8u newm;
|
||||
Bit8u extp;
|
||||
Bit8u panch;
|
||||
Bit8u nts;
|
||||
Bit8u rhy;
|
||||
Bit8u vibpos;
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
virtual const char * midi_synth_name(void) = 0;
|
||||
virtual unsigned int midi_bank_count(void) = 0;
|
||||
virtual const char * midi_bank_name(unsigned int bank) = 0;
|
||||
virtual int midi_init(unsigned int rate, unsigned int bank) = 0;
|
||||
virtual int midi_init(unsigned int rate, unsigned int bank, unsigned int extp) = 0;
|
||||
virtual void midi_write(unsigned int data) = 0;
|
||||
virtual void midi_generate(signed short *buffer, unsigned int length) = 0;
|
||||
};
|
||||
|
|
|
@ -93,6 +93,11 @@ void DoomOPL::OPL_InitRegisters(bool opl_new)
|
|||
{
|
||||
OPL_WriteRegister(OPL_REG_NEW_MODE, 0x01);
|
||||
}
|
||||
|
||||
if (opl_extp)
|
||||
{
|
||||
OPL_WriteRegister(0x106, 0x17);
|
||||
}
|
||||
}
|
||||
|
||||
// Load instrument table from GENMIDI lump:
|
||||
|
@ -307,6 +312,16 @@ void DoomOPL::SetVoicePan(opl_voice_t *voice, unsigned int pan)
|
|||
opl_voice->feedback | pan);
|
||||
}
|
||||
|
||||
void DoomOPL::SetVoicePanEx(opl_voice_t *voice, unsigned int pan)
|
||||
{
|
||||
const genmidi_voice_t *opl_voice;
|
||||
|
||||
opl_voice = &voice->current_instr->voices[voice->current_instr_voice];
|
||||
|
||||
OPL_WriteRegister(0x107, voice->index + (voice->array * 9 / 256));
|
||||
OPL_WriteRegister(0x108, pan * 2);
|
||||
}
|
||||
|
||||
// Initialize the voice table and freelist
|
||||
|
||||
void DoomOPL::InitVoices(void)
|
||||
|
@ -583,6 +598,11 @@ void DoomOPL::VoiceKeyOn(opl_channel_data_t *channel,
|
|||
// Set the volume level.
|
||||
|
||||
SetVoiceVolume(voice, volume);
|
||||
|
||||
// Set the extended panning, if necessary
|
||||
|
||||
if (opl_extp)
|
||||
SetVoicePanEx(voice, channel->panex);
|
||||
|
||||
// Write the frequency value to turn the note on.
|
||||
|
||||
|
@ -712,26 +732,43 @@ void DoomOPL::SetChannelPan(opl_channel_data_t *channel, unsigned int pan)
|
|||
|
||||
if (opl_new)
|
||||
{
|
||||
if (pan >= 96)
|
||||
if (opl_extp)
|
||||
{
|
||||
reg_pan = 0x10;
|
||||
}
|
||||
else if (pan <= 48)
|
||||
{
|
||||
reg_pan = 0x20;
|
||||
if (channel->panex != pan)
|
||||
{
|
||||
channel->panex = pan;
|
||||
for (i = 0; i < voice_alloced_num; i++)
|
||||
{
|
||||
if (voice_alloced_list[i]->channel == channel)
|
||||
{
|
||||
SetVoicePanEx(voice_alloced_list[i], pan);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
reg_pan = 0x30;
|
||||
}
|
||||
if (channel->pan != reg_pan)
|
||||
{
|
||||
channel->pan = reg_pan;
|
||||
for (i = 0; i < voice_alloced_num; i++)
|
||||
if (pan >= 96)
|
||||
{
|
||||
if (voice_alloced_list[i]->channel == channel)
|
||||
reg_pan = 0x10;
|
||||
}
|
||||
else if (pan <= 48)
|
||||
{
|
||||
reg_pan = 0x20;
|
||||
}
|
||||
else
|
||||
{
|
||||
reg_pan = 0x30;
|
||||
}
|
||||
if (channel->pan != reg_pan)
|
||||
{
|
||||
channel->pan = reg_pan;
|
||||
for (i = 0; i < voice_alloced_num; i++)
|
||||
{
|
||||
SetVoicePan(voice_alloced_list[i], reg_pan);
|
||||
if (voice_alloced_list[i]->channel == channel)
|
||||
{
|
||||
SetVoicePan(voice_alloced_list[i], reg_pan);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -881,10 +918,11 @@ void DoomOPL::InitChannel(opl_channel_data_t *channel)
|
|||
channel->instrument = &main_instrs[0];
|
||||
channel->volume = 127;
|
||||
channel->pan = 0x30;
|
||||
channel->panex = 64;
|
||||
channel->bend = 0;
|
||||
}
|
||||
|
||||
int DoomOPL::midi_init(unsigned int rate, unsigned int bank)
|
||||
int DoomOPL::midi_init(unsigned int rate, unsigned int bank, unsigned int extp)
|
||||
{
|
||||
/*char *env;*/
|
||||
unsigned int i;
|
||||
|
@ -894,7 +932,9 @@ int DoomOPL::midi_init(unsigned int rate, unsigned int bank)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
opl_extp = !!extp;
|
||||
|
||||
memset(channels, 0, sizeof(channels));
|
||||
main_instrs = NULL;
|
||||
percussion_instrs = NULL;
|
||||
|
|
|
@ -116,7 +116,7 @@ typedef struct
|
|||
|
||||
// Pan value
|
||||
|
||||
int pan;
|
||||
int pan, panex;
|
||||
|
||||
// Pitch bend value:
|
||||
|
||||
|
@ -347,6 +347,7 @@ private:
|
|||
unsigned int voice_alloced_num = 0;
|
||||
|
||||
bool opl_new;
|
||||
bool opl_extp;
|
||||
unsigned int opl_voices;
|
||||
|
||||
void OPL_WriteRegister(unsigned int reg, unsigned char data);
|
||||
|
@ -357,6 +358,7 @@ private:
|
|||
void SetVoiceInstrument(opl_voice_t *voice, const genmidi_instr_t *instr, unsigned int instr_voice);
|
||||
void SetVoiceVolume(opl_voice_t *voice, unsigned int volume);
|
||||
void SetVoicePan(opl_voice_t *voice, unsigned int pan);
|
||||
void SetVoicePanEx(opl_voice_t *voice, unsigned int pan);
|
||||
void InitVoices(void);
|
||||
void VoiceKeyOff(opl_voice_t *voice);
|
||||
opl_channel_data_t *TrackChannelForEvent(unsigned char channel_num);
|
||||
|
@ -379,7 +381,7 @@ public:
|
|||
const char * midi_synth_name(void);
|
||||
unsigned int midi_bank_count(void);
|
||||
const char * midi_bank_name(unsigned int bank);
|
||||
int midi_init(unsigned int rate, unsigned int bank);
|
||||
int midi_init(unsigned int rate, unsigned int bank, unsigned int extp);
|
||||
void midi_write(unsigned int data);
|
||||
void midi_generate(signed short *buffer, unsigned int length);
|
||||
};
|
||||
|
|
|
@ -223,6 +223,12 @@ void OPL3MIDI::opl_midikeyon(opl_channel *channel, byte note, opl_timbre *timbre
|
|||
opl_writereg(OPL_FNUM + voice->num, freqpitched & 0xff);
|
||||
opl_writereg(OPL_FEEDBACK + voice->num, fb);
|
||||
opl_writereg(OPL_BLOCK + voice->num, (freqpitched >> 8) | 0x20);
|
||||
|
||||
if (opl_extp)
|
||||
{
|
||||
opl_writereg(0x107, (voice->num & 0xFF) + ((voice->num / 256) * 9));
|
||||
opl_writereg(0x108, channel->panex * 2);
|
||||
}
|
||||
|
||||
voice->freq = freq;
|
||||
voice->freqpitched = freqpitched;
|
||||
|
@ -305,6 +311,12 @@ void OPL3MIDI::opl_updatevolpan(opl_channel *channel)
|
|||
opl_writereg(OPL_TL + opl_voices[i].car, carvol);
|
||||
|
||||
opl_writereg(OPL_FEEDBACK + opl_voices[i].num, opl_voices[i].timbre->fb & channel->pan);
|
||||
|
||||
if (opl_extp)
|
||||
{
|
||||
opl_writereg(0x107, (opl_voices[i].num & 0xFF) + ((opl_voices[i].num & 0x100) * 9 / 256));
|
||||
opl_writereg(0x108, channel->panex * 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -317,17 +329,24 @@ void OPL3MIDI::opl_updatevol(opl_channel *channel, byte vol)
|
|||
|
||||
void OPL3MIDI::opl_updatepan(opl_channel *channel, byte pan)
|
||||
{
|
||||
if (pan < 48)
|
||||
if (opl_extp)
|
||||
{
|
||||
channel->pan = 0xdf;
|
||||
}
|
||||
else if(pan > 80)
|
||||
{
|
||||
channel->pan = 0xef;
|
||||
channel->panex = pan;
|
||||
}
|
||||
else
|
||||
{
|
||||
channel->pan = 0xff;
|
||||
if (pan < 48)
|
||||
{
|
||||
channel->pan = 0xdf;
|
||||
}
|
||||
else if(pan > 80)
|
||||
{
|
||||
channel->pan = 0xef;
|
||||
}
|
||||
else
|
||||
{
|
||||
channel->pan = 0xff;
|
||||
}
|
||||
}
|
||||
opl_updatevolpan(channel);
|
||||
}
|
||||
|
@ -414,7 +433,7 @@ void OPL3MIDI::opl_midipitchbend(opl_channel *channel, byte parm1, byte parm2)
|
|||
}
|
||||
|
||||
|
||||
int OPL3MIDI::midi_init(unsigned int rate, unsigned int bank)
|
||||
int OPL3MIDI::midi_init(unsigned int rate, unsigned int bank, unsigned int extp)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
|
@ -425,6 +444,11 @@ int OPL3MIDI::midi_init(unsigned int rate, unsigned int bank)
|
|||
}
|
||||
|
||||
opl_opl3mode = true;
|
||||
|
||||
opl_extp = !!extp;
|
||||
|
||||
if (opl_extp)
|
||||
opl_writereg(0x106, 0x17);
|
||||
|
||||
opl_writereg(OPL_LSI, 0x00);
|
||||
opl_writereg(OPL_TIMER, 0x60);
|
||||
|
@ -489,6 +513,7 @@ int OPL3MIDI::midi_init(unsigned int rate, unsigned int bank)
|
|||
opl_channels[i].pitch = 0;
|
||||
opl_channels[i].volume = 0;
|
||||
opl_channels[i].pan = 0xff;
|
||||
opl_channels[i].panex = 64;
|
||||
opl_channels[i].sustained = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ typedef struct
|
|||
opl_timbre *timbre;
|
||||
int32_t pitch;
|
||||
uint32_t volume;
|
||||
uint32_t pan;
|
||||
uint32_t pan, panex;
|
||||
bool sustained;
|
||||
} opl_channel;
|
||||
|
||||
|
@ -91,6 +91,7 @@ class OPL3MIDI : public midisynth {
|
|||
private:
|
||||
fm_chip *opl_chip;
|
||||
bool opl_opl3mode;
|
||||
bool opl_extp;
|
||||
|
||||
uint32_t opl_voice_num;
|
||||
|
||||
|
@ -125,7 +126,7 @@ public:
|
|||
const char *midi_synth_name(void);
|
||||
unsigned int midi_bank_count(void);
|
||||
const char * midi_bank_name(unsigned int bank);
|
||||
int midi_init(unsigned int rate, unsigned int bank);
|
||||
int midi_init(unsigned int rate, unsigned int bank, unsigned int extp);
|
||||
void midi_write(unsigned int data);
|
||||
void midi_generate(signed short *buffer, unsigned int length);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue