Pitch bend is not unreasonable

This commit is contained in:
Robin Gareus 2024-04-09 02:09:56 +02:00
parent 4a0505979d
commit 826103f08c
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
1 changed files with 25 additions and 3 deletions

View File

@ -46,6 +46,7 @@ enum RMIDI_EV_TYPE {
NOTE_OFF, NOTE_OFF,
PROGRAM_CHANGE, PROGRAM_CHANGE,
CONTROL_CHANGE, CONTROL_CHANGE,
PITCH_BEND,
}; };
struct rmidi_event_t { struct rmidi_event_t {
@ -60,6 +61,10 @@ struct rmidi_event_t {
uint8_t param; uint8_t param;
uint8_t value; uint8_t value;
} control; } control;
struct {
uint8_t lo;
uint8_t hi;
} bend;
} d; } d;
}; };
@ -78,8 +83,9 @@ typedef struct _RSSynthChannel {
int8_t midimsgs[128]; // internal, note-off + on in same cycle, sustained-off int8_t midimsgs[128]; // internal, note-off + on in same cycle, sustained-off
int8_t sustain; // sustain pedal pressed int8_t sustain; // sustain pedal pressed
ADSRcfg adsr; ADSRcfg adsr;
float pitch_bend;
void (*synthesize) (struct _RSSynthChannel* sc, void (*synthesize) (struct _RSSynthChannel* sc,
const uint8_t note, const float vol, const float pc, const uint8_t note, const float vol, float pc,
const size_t n_samples, float* left, float* right); const size_t n_samples, float* left, float* right);
} RSSynthChannel; } RSSynthChannel;
@ -180,12 +186,16 @@ adsr_env (RSSynthChannel* sc, const uint8_t note)
/* piano like sound w/slight stereo phase */ /* piano like sound w/slight stereo phase */
static void static void
synthesize_sineP (RSSynthChannel* sc, synthesize_sineP (RSSynthChannel* sc,
const uint8_t note, const float vol, const float fq, const uint8_t note, const float vol, float fq,
const size_t n_samples, float* left, float* right) const size_t n_samples, float* left, float* right)
{ {
size_t i; size_t i;
float phase = sc->phase[note]; float phase = sc->phase[note];
if (sc->pitch_bend != 1) {
fq *= sc->pitch_bend;
}
for (i = 0; i < n_samples; ++i) { for (i = 0; i < n_samples; ++i) {
float env = adsr_env (sc, note); float env = adsr_env (sc, note);
if (sc->adsr_cnt[note] == 0) { if (sc->adsr_cnt[note] == 0) {
@ -337,7 +347,8 @@ synth_reset_channel (RSSynthChannel* sc)
sc->miditable[k] = 0; sc->miditable[k] = 0;
sc->midimsgs[k] = 0; sc->midimsgs[k] = 0;
} }
sc->keycomp = 0; sc->keycomp = 0;
sc->pitch_bend = 1.0;
} }
static void static void
@ -398,6 +409,12 @@ synth_process_midi_event (void* synth, struct rmidi_event_t* ev)
/* params 122-127 are reserved - skip them. */ /* params 122-127 are reserved - skip them. */
} }
break; break;
case PITCH_BEND:
{
float st = ((((int)ev->d.bend.hi << 7) | ev->d.bend.lo) - 8192) / 4096.0; // +/- 2 semitones
rs->sc[ev->channel].pitch_bend = powf (2, st / 12.0);
}
break;
default: default:
break; break;
} }
@ -484,6 +501,11 @@ synth_parse_midi (void* synth, const uint8_t* data, const size_t size)
ev.type = PROGRAM_CHANGE; ev.type = PROGRAM_CHANGE;
ev.d.control.value = data[1] & 0x7f; ev.d.control.value = data[1] & 0x7f;
break; break;
case 0xE0:
ev.type = PITCH_BEND;
ev.d.bend.lo = data[1] & 0x7f;
ev.d.bend.hi = data[2] & 0x7f;
break;
default: default:
return; return;
} }