[AD] midi length + midi frequency |
[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
In response to a request on [Al], attached is a patch which adds a
function get_midi_length(). While making it, I noticed that the midi
player only is called 40 times / second. I understand nothing of music
at all, but I know there are sometimes 64th notes in music (now if that
means they are 1/64th second long, I don't know) - anyway, it was easy
to do, so I added another function to change the maximum timer frequency
the midi player uses. I tried changing it to 64 with some midis I found,
but can't here any difference to 40.. so maybe this is quite unrelated
after all.
--
Elias Pschernig
Index: src/midi.c
===================================================================
RCS file: /cvsroot/alleg/allegro/src/midi.c,v
retrieving revision 1.20
diff -u -p -r1.20 midi.c
--- src/midi.c 12 Mar 2005 05:47:18 -0000 1.20
+++ src/midi.c 17 Mar 2005 15:59:25 -0000
@@ -14,6 +14,8 @@
*
* Pause and seek functions by George Foot.
*
+ * get_midi_length by Elias Pschernig.
+ *
* See readme.txt for copyright information.
*/
@@ -77,6 +79,7 @@ typedef struct PATCH_TABLE
volatile long midi_pos = -1; /* position in MIDI file */
+volatile long midi_time = 0; /* position in milli seconds */
static long midi_pos_counter; /* delta for midi_pos */
volatile long _midi_tick = 0; /* counter for killing notes */
@@ -95,6 +98,7 @@ long midi_loop_end = -1;
static int midi_semaphore = 0; /* reentrancy flag */
static int midi_loaded_patches = FALSE; /* loaded entire patch set? */
+static int midi_timer_frequency = 40; /* how often the midi callback gets called */
static long midi_timer_speed; /* midi_player's timer speed */
static int midi_pos_speed; /* MIDI delta -> midi_pos */
static int midi_speed; /* MIDI delta -> timer */
@@ -875,14 +879,16 @@ static void midi_player(void)
return;
if (midi_semaphore) {
- midi_timer_speed += BPS_TO_TIMER(40);
- install_int_ex(midi_player, BPS_TO_TIMER(40));
+ midi_timer_speed += BPS_TO_TIMER(midi_timer_frequency);
+ install_int_ex(midi_player, BPS_TO_TIMER(midi_timer_frequency));
return;
}
midi_semaphore = TRUE;
_midi_tick++;
+ midi_time += midi_timer_speed;
+
do_it_all_again:
for (c=0; c<MIDI_VOICES; c++)
@@ -976,8 +982,8 @@ static void midi_player(void)
}
/* reprogram the timer */
- if (midi_timer_speed < BPS_TO_TIMER(40))
- midi_timer_speed = BPS_TO_TIMER(40);
+ if (midi_timer_speed < BPS_TO_TIMER(midi_timer_frequency))
+ midi_timer_speed = BPS_TO_TIMER(midi_timer_frequency);
if (!midi_seeking)
install_int_ex(midi_player, midi_timer_speed);
@@ -1184,6 +1190,7 @@ static void prepare_to_play(MIDI *midi)
midifile = midi;
midi_pos = 0;
+ midi_time = 0;
midi_pos_counter = 0;
midi_speed = TIMERS_PER_SECOND / 2 / midifile->divisions; /* 120 bpm */
midi_new_speed = -1;
@@ -1446,6 +1453,34 @@ END_OF_FUNCTION(midi_seek);
+/* set_midi_frequency:
+ * Allows to change how often the midi player is called per second, default is
+ * 40 times. There's usually no need to change this, since the accuracy at
+ * which Allegro timer's are called isn't much higher in most operating
+ * systems.
+ */
+void set_midi_frequency(int f)
+{
+ midi_timer_frequency = f;
+}
+
+
+
+/* get_midi_length:
+ * Returns the length, in seconds, of the specified midi. This will stop any
+ * currently playing midi. Don't call it too often, since it simulates playing
+ * all of the midi to get the time even if the midi contains tempo changes.
+ */
+int get_midi_length(MIDI *midi)
+{
+ play_midi(midi, 0);
+ while (midi_pos < 0);
+ midi_seek(INT_MAX);
+ return midi_time / TIMERS_PER_SECOND;
+}
+
+
+
/* midi_out:
* Inserts MIDI command bytes into the output stream, in realtime.
*/
@@ -1498,6 +1533,7 @@ int load_midi_patches(void)
static void midi_lock_mem(void)
{
LOCK_VARIABLE(midi_pos);
+ LOCK_VARIABLE(midi_time);
LOCK_VARIABLE(midi_pos_counter);
LOCK_VARIABLE(_midi_tick);
LOCK_VARIABLE(midifile);
@@ -1505,6 +1541,7 @@ static void midi_lock_mem(void)
LOCK_VARIABLE(midi_loop);
LOCK_VARIABLE(midi_loop_start);
LOCK_VARIABLE(midi_loop_end);
+ LOCK_VARIABLE(midi_timer_frequency);
LOCK_VARIABLE(midi_timer_speed);
LOCK_VARIABLE(midi_pos_speed);
LOCK_VARIABLE(midi_speed);
Index: include/allegro/midi.h
===================================================================
RCS file: /cvsroot/alleg/allegro/include/allegro/midi.h,v
retrieving revision 1.2
diff -u -p -r1.2 midi.h
--- include/allegro/midi.h 31 Oct 2002 12:56:24 -0000 1.2
+++ include/allegro/midi.h 17 Mar 2005 15:59:25 -0000
@@ -121,8 +121,10 @@ AL_FUNC(void, stop_midi, (void));
AL_FUNC(void, midi_pause, (void));
AL_FUNC(void, midi_resume, (void));
AL_FUNC(int, midi_seek, (int target));
+AL_FUNC(int, get_midi_length, (MIDI *midi));
AL_FUNC(void, midi_out, (unsigned char *data, int length));
AL_FUNC(int, load_midi_patches, (void));
+AL_FUNC(void, set_midi_frequency, (int f));
AL_FUNCPTR(void, midi_msg_callback, (int msg, int byte1, int byte2));
AL_FUNCPTR(void, midi_meta_callback, (int type, AL_CONST unsigned char *data, int length));