1 /*(LGPL)
2 ---------------------------------------------------------------------------
3 	a_sequencer.c - MIDI Sequencer
4 ---------------------------------------------------------------------------
5  * Copyright (C) 2002, David Olofson
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by
9  * the Free Software Foundation; either version 2.1 of the License, or (at
10  * your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21 
22 #include "a_globals.h"
23 #include "a_struct.h"
24 
25 #include "a_sequencer.h"
26 #include "a_midisock.h"
27 
28 /*
29  * Temporary MIDI playback hack.
30  *
31  * Only one sequence at a time, and it uses the
32  * same midisock as the external MIDI input.
33  */
34 
35 midi_player_t *midiplayer = 0;
36 static float fs = 44100;
37 
38 
sequencer_open(midisock_t * ms,float framerate)39 int sequencer_open(midisock_t *ms, float framerate)
40 {
41 	aev_client("sequencer_open()");
42 	fs = framerate;
43 #if 1
44 	midiplayer = mp_open(ms);
45 #else
46 	midiplayer = mp_open(&monitor_midisock);
47 #endif
48 	return (midiplayer != 0);
49 }
50 
51 
sequencer_close(void)52 void sequencer_close(void)
53 {
54 	aev_client("sequencer_close()");
55 	if(!midiplayer)
56 		return;
57 
58 	mp_close(midiplayer);
59 	midiplayer = 0;
60 }
61 
62 
sequencer_play(midi_file_t * mf,int tag,int pitch,int volume)63 int sequencer_play(midi_file_t *mf, int tag, int pitch, int volume)
64 {
65 	aev_client("sequencer_play()");
66 	if(!midiplayer)
67 		return -1;
68 
69 	midiplayer->pitch = pitch - (60 << 16);
70 	mp_select(midiplayer, mf);
71 	return 0;
72 }
73 
74 
sequencer_stop(int tag)75 void sequencer_stop(int tag)
76 {
77 	aev_client("sequencer_stop()");
78 	if(!midiplayer)
79 		return;
80 
81 	mp_stop(midiplayer);
82 }
83 
84 
sequencer_playing(int tag)85 int sequencer_playing(int tag)
86 {
87 	if(!midiplayer)
88 		return 0;
89 
90 	return (midiplayer->mf != 0);
91 }
92 
93 
sequencer_process(unsigned frames)94 void sequencer_process(unsigned frames)
95 {
96 	int i;
97 	aev_client("sequencer_process()");
98 	if(!midiplayer)
99 		return;
100 
101 	if(mp_play(midiplayer, (float)frames / fs))
102 		return;
103 
104 	for(i = 0; i < AUDIO_MAX_CHANNELS; ++i)
105 	{
106 		int wave;
107 		if(!channeltab[i].playing)
108 			continue;
109 		wave = patchtab[channeltab[i].ctl[ACC_PATCH]].param[APP_WAVE];
110 		if((wave < 0) || (wave >= AUDIO_MAX_WAVES))
111 			continue;
112 		if(AF_MIDI != wavetab[wave].format)
113 			continue;
114 		channeltab[i].playing = 0;
115 	}
116 }
117