<commit_before>/* midi.c
 *
 * Adlib OPL2/OPL3 FM synthesizer chipset test program.
 * Play MIDI file using the OPLx synthesizer (well, poorly anyway)
 * (C) 2010-2012 <NAME>.
 * Hackipedia DOS library.
 *
 * This code is licensed under the LGPL.
 * <insert LGPL legal text here>
 *
 * Compiles for intended target environments:
 *   - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box]
 */
 
#include <stdio.h>
#include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <malloc.h>
#include <ctype.h>
#include <fcntl.h>
#include <math.h>
#include <dos.h>

#include <hw/vga/vga.h>
#include <hw/dos/dos.h>
#include <hw/8254/8254.h>		/* 8254 timer */
#include <hw/8259/8259.h>
#include <hw/vga/vgagui.h>
#include <hw/vga/vgatty.h>
#include <hw/adlib/adlib.h>

struct midi_channel {
	unsigned char		note_number;
	unsigned char		note_velocity;
	unsigned int		note_on:1;
};

struct midi_track {
	/* track data, raw */
	unsigned char*		raw;		/* raw data base */
	unsigned char*		fence;		/* raw data end (last byte + 1) */
	unsigned char*		read;		/* raw data read ptr */
	/* state */
	unsigned long		us_per_quarter_note; /* Microseconds per quarter note (def 120 BPM) */
	unsigned long		us_tick_cnt_mtpq; /* Microseconds advanced (up to 10000 us or one unit at 100Hz) x ticks per quarter note */
	unsigned long		wait;
	unsigned char		last_status;	/* MIDI last status byte */
};

#define MIDI_MAX_CHANNELS	16
#define MIDI_MAX_TRACKS		64

struct midi_channel		midi_ch[MIDI_MAX_CHANNELS];
struct midi_track		midi_trk[MIDI_MAX_TRACKS];
static unsigned int		midi_trk_count=0;
static unsigned char		midi_playing=0;

/* MIDI params. Nobody ever said it was a straightforward standard!
 * NTS: These are for reading reference. Internally we convert everything to 100Hz time base. */
static unsigned int ticks_per_quarter_note=0;	/* "Ticks per beat" */

static unsigned int irq0_cnt=0,irq0_add=0,irq0_max=0;
static void (interrupt *old_irq0)();
static unsigned long irq0_ticks=0;

static inline unsigned char midi_trk_read(struct midi_track *t) {
	unsigned char c;

	if (t->read == NULL || t->read >= t->fence) return 0xFF;
	c = *(t->read);
	t->read++;
	return c;
}

static double midi_notes[0x80];

static double midi_note_freq(struct midi_channel *ch,unsigned char key) {
	return midi_notes[key&0x7F];
}

static inline void on_key_on(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char vel) {
	unsigned int ach = (unsigned int)(ch - midi_ch); /* pointer math */
	double freq = midi_note_freq(ch,key);

#if 1
	fprintf(stderr,"on ach=%u\n",ach);
#endif

	if (ch->note_on) {
		adlib_fm[ach].mod.key_on = 0;
		adlib_update_groupA0(ach,&adlib_fm[ach]);
	}

	ch->note_on = 1;
	ch->note_number = key;
	ch->note_velocity = vel;

	adlib_freq_to_fm_op(&adlib_fm[ach].mod,freq);
	adlib_fm[ach].mod.key_on = 1;
	adlib_update_groupA0(ach,&adlib_fm[ach]);
}

static inline void on_key_off(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char vel) {<commit_msg>remove key on rekey hack<commit_after>/* midi.c
 *
 * Adlib OPL2/OPL3 FM synthesizer chipset test program.
 * Play MIDI file using the OPLx synthesizer (well, poorly anyway)
 * (C) 2010-2012 <NAME>.
 * Hackipedia DOS library.
 *
 * This code is licensed under the LGPL.
 * <insert LGPL legal text here>
 *
 * Compiles for intended target environments:
 *   - MS-DOS [pure DOS mode, or Windows or OS/2 DOS Box]
 */
 
#include <stdio.h>
#include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <malloc.h>
#include <ctype.h>
#include <fcntl.h>
#include <math.h>
#include <dos.h>

#include <hw/vga/vga.h>
#include <hw/dos/dos.h>
#include <hw/8254/8254.h>		/* 8254 timer */
#include <hw/8259/8259.h>
#include <hw/vga/vgagui.h>
#include <hw/vga/vgatty.h>
#include <hw/adlib/adlib.h>

struct midi_channel {
	unsigned char		note_number;
	unsigned char		note_velocity;
	unsigned int		note_on:1;
};

struct midi_track {
	/* track data, raw */
	unsigned char*		raw;		/* raw data base */
	unsigned char*		fence;		/* raw data end (last byte + 1) */
	unsigned char*		read;		/* raw data read ptr */
	/* state */
	unsigned long		us_per_quarter_note; /* Microseconds per quarter note (def 120 BPM) */
	unsigned long		us_tick_cnt_mtpq; /* Microseconds advanced (up to 10000 us or one unit at 100Hz) x ticks per quarter note */
	unsigned long		wait;
	unsigned char		last_status;	/* MIDI last status byte */
};

#define MIDI_MAX_CHANNELS	16
#define MIDI_MAX_TRACKS		64

struct midi_channel		midi_ch[MIDI_MAX_CHANNELS];
struct midi_track		midi_trk[MIDI_MAX_TRACKS];
static unsigned int		midi_trk_count=0;
static unsigned char		midi_playing=0;

/* MIDI params. Nobody ever said it was a straightforward standard!
 * NTS: These are for reading reference. Internally we convert everything to 100Hz time base. */
static unsigned int ticks_per_quarter_note=0;	/* "Ticks per beat" */

static unsigned int irq0_cnt=0,irq0_add=0,irq0_max=0;
static void (interrupt *old_irq0)();
static unsigned long irq0_ticks=0;

static inline unsigned char midi_trk_read(struct midi_track *t) {
	unsigned char c;

	if (t->read == NULL || t->read >= t->fence) return 0xFF;
	c = *(t->read);
	t->read++;
	return c;
}

static double midi_notes[0x80];

static double midi_note_freq(struct midi_channel *ch,unsigned char key) {
	return midi_notes[key&0x7F];
}

static inline void on_key_on(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char vel) {
	unsigned int ach = (unsigned int)(ch - midi_ch); /* pointer math */
	double freq = midi_note_freq(ch,key);

#if 1
	fprintf(stderr,"on ach=%u\n",ach);
#endif

	ch->note_on = 1;
	ch->note_number = key;
	ch->note_velocity = vel;

	adlib_freq_to_fm_op(&adlib_fm[ach].mod,freq);
	adlib_fm[ach].mod.key_on = 1;
	adlib_update_groupA0(ach,&adlib_fm[ach]);
}

static inline void on_key_off(struct midi_track *t,struct midi_channel *ch,unsigned char key,unsigned char vel) {
{'fraction_non_alphanumeric': 0.12299818391943206, 'fraction_numerical': 0.02443453855043751, 'mean_word_length': 4.394479073909172, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 60, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2525503', 'n_tokens_mistral': 2445, 'n_tokens_neox': 2302, 'n_words': 655}