Cog/Plugins/MIDI/MIDI/synthlib_opl3w/opl3midi.h

133 lines
3.8 KiB
C
Raw Normal View History

//
// Copyright (C) 2015-2016 Alexey Khokholov (Nuke.YKT)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
#pragma once
#include <stdint.h>
#include "opl3type.h"
#include "gmtimbre.h"
#include "../interface.h"
#define OPL_LSI 0x00
#define OPL_TIMER 0x04
#define OPL_4OP 0x104
#define OPL_NEW 0x105
#define OPL_NTS 0x08
#define OPL_MULT 0x20
#define OPL_TL 0x40
#define OPL_AD 0x60
#define OPL_SR 0x80
#define OPL_WAVE 0xe0
#define OPL_FNUM 0xa0
#define OPL_BLOCK 0xb0
#define OPL_RHYTHM 0xbd
#define OPL_FEEDBACK 0xc0
#define MIDI_DRUMCHANNEL 9
#define MIDI_NOTEOFF 0x80
#define MIDI_NOTEON 0x90
#define MIDI_CONTROL 0xb0
#define MIDI_CONTROL_VOL 0x07
#define MIDI_CONTROL_BAL 0x08
#define MIDI_CONTROL_PAN 0x0a
#define MIDI_CONTROL_SUS 0x40
#define MIDI_CONTROL_ALLOFF 0x78
#define MIDI_PROGRAM 0xc0
#define MIDI_PITCHBEND 0xe0
const double opl_samplerate = 50000.0;
const double opl_tune = 440.0;
const byte opl_pitchfrac = 8;
const byte opl_volume_map[32] =
{
80, 63, 40, 36, 32, 28, 23, 21,
19, 17, 15, 14, 13, 12, 11, 10,
9, 8, 7, 6, 5, 5, 4, 4,
3, 3, 2, 2, 1, 1, 0, 0
};
const byte opl_voice_map[9]
{
0, 1, 2, 8, 9, 10, 16, 17, 18
};
typedef struct
{
opl_timbre *timbre;
int32_t pitch;
uint32_t volume;
uint32_t pan, panex;
bool sustained;
} opl_channel;
typedef struct
{
uint32_t num;
uint32_t mod, car;
uint32_t freq;
uint32_t freqpitched;
uint32_t time;
byte note;
byte velocity;
bool keyon;
bool sustained;
opl_timbre* timbre;
opl_channel *channel;
} opl_voice;
class OPL3MIDI : public midisynth {
private:
fm_chip *opl_chip;
bool opl_opl3mode;
bool opl_extp;
uint32_t opl_voice_num;
opl_channel opl_channels[16];
opl_voice opl_voices[18];
uint32_t opl_freq[12];
uint32_t opl_time;
int32_t opl_uppitch;
int32_t opl_downpitch;
void opl_writereg(uint32_t reg, byte data);
uint32_t opl_tofnum(double freq);
void opl_buildfreqtable(void);
uint32_t opl_calcblock(uint32_t fnum);
uint32_t opl_applypitch(uint32_t freq, int32_t pitch);
opl_voice * opl_allocvoice(opl_timbre *timbre);
opl_voice * opl_findvoice(opl_channel *channel, byte note);
void opl_midikeyon(opl_channel *channel, byte note, opl_timbre *timbre, byte velocity);
void opl_midikeyoff(opl_channel *channel, byte note, opl_timbre *timbre, bool sustained);
void opl_midikeyoffall(opl_channel *channel);
void opl_updatevolpan(opl_channel *channel);
void opl_updatevol(opl_channel *channel, byte vol);
void opl_updatepan(opl_channel *channel, byte pan);
void opl_updatesustain(opl_channel *channel, byte sustain);
void opl_updatepitch(opl_channel *channel);
void opl_midicontrol(opl_channel *channel, byte type, byte data);
void opl_midiprogram(opl_channel *channel, byte program);
void opl_midipitchbend(opl_channel *channel, byte parm1, byte parm2);
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, unsigned int extp);
void midi_write(unsigned int data);
void midi_generate(signed short *buffer, unsigned int length);
};