-
[sound-tools/ossmidi.git] / midiio.c
1 /* midiio.c
2  *
3  * author: hackbard
4  *
5  */
6
7 #include <stdio.h>
8 #include <string.h>
9 #include <stdlib.h>
10
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <fcntl.h>
14 #include <unistd.h>
15
16 #include <sys/soundcard.h>
17
18 #include "midiio.h"
19
20 /* soem defines */
21 #define MIDI_DEVICE "/dev/midi"
22 #define NOTE_ON 0x90
23 #define NOTE_OFF 0x80
24 #define NOTE_DATA 0x7F
25 #define CH_MASK 0x0F
26 #define VEL_MASK 0x7F
27
28 #define MSB_MASK 0xF0
29 #define LSB_MASK 0x0F
30
31
32 /* global, do we need sockets global? */
33 int midi_fd;
34
35 int all_stop(int fd) {
36  int i,j;
37  for(j=0;j<16;j++)
38   for(i=0;i<128;i++)
39    note_off(fd,j,i,(int)0x7F);
40  return 0;
41 }
42
43 int midi_write_msg3(int fd,unsigned char status,unsigned char data1,unsigned char data2) {
44  unsigned char buf[3];
45  buf[0]=status;
46  buf[1]=data1;
47  buf[2]=data2;
48  write(fd,buf,3);
49  return 0;
50 }
51
52 int midi_write_msg2(int fd,unsigned char status,unsigned char data1) {
53  unsigned char buf[2];
54  buf[0]=status;
55  buf[1]=data1;
56  write(fd,buf,2);
57  return 0;
58 }
59
60 int note_on(int fd,int chan,int note,int vel) {
61  midi_write_msg3(fd,NOTE_ON|(CH_MASK&chan),note&NOTE_DATA,vel&VEL_MASK);
62  return 0;
63 }
64
65 int note_off(int fd,int chan,int note,int vel) {
66  midi_write_msg3(fd,NOTE_OFF|(CH_MASK&chan),note&NOTE_DATA,vel&VEL_MASK);
67  return 0;
68 }
69
70 int midi_read(int fd,char *buf) {
71  int bytes_read;
72  bytes_read=read(fd,buf,1);
73  return bytes_read;
74 }
75
76 int midi_read_msg(int fd,char *buf) {
77  char tmp_buf;
78  int i;
79  midi_read(fd,&tmp_buf);
80  buf[0]=tmp_buf;
81
82  /* decide how much to read */
83  if(((buf[0]&MSB_MASK)==PROGRAM_CHANGE) || ((buf[0]&MSB_MASK)==CHANNEL_PRESSURE)) {
84   printf("debug: program change or channel pressure event detected\n");
85   midi_read(fd,&tmp_buf);
86   buf[1]=tmp_buf;
87   return 2;
88  } else {
89   printf("debug: none program change or channel pressure event detected\n");
90   for(i=0;i<2;i++) {
91    midi_read(fd,&tmp_buf);
92    buf[i+1]=tmp_buf;
93   }
94   return 3;
95  }
96 }
97  
98
99
100
101 #ifdef TEST_API
102 /* test the io api ... */
103
104 int main(int argc,char **argv) {
105
106  int note,channel,i,j,k;
107  char my_buf[3];
108
109  if(argc>1) {
110   note=atoi(argv[2]);
111   channel=atoi(argv[1]);
112  }
113
114  midi_fd=open(MIDI_DEVICE,O_RDWR);
115  printf("debug: midi_fd = %d\n",midi_fd);
116
117  printf("reading ...\n");
118  i=midi_read_msg(midi_fd,&my_buf[1]);
119  printf("debug: i = %d\n",i);
120  for(k=0;k<i;k++) {
121   for(j=7;j>=0;j--) printf("%s%d%s",(j==7?"|":""),
122                                 (((int)my_buf[k] & (1<<j))>0?1:0),
123                                 (j==0?"|\t":"|"));
124  }
125  printf("\n");
126  printf("sleep for 3 secs ...\n");
127  sleep(3);
128
129  all_stop(midi_fd);
130  sleep(2);
131
132  for(i=0;i<4;i++) {
133   note_off(midi_fd,0,38,127);
134   note_off(midi_fd,0,42,127);
135   note_on(midi_fd,0,42,127);
136   note_on(midi_fd,0,38,127);
137   sleep(1);
138   note_off(midi_fd,0,42,127);
139   note_on(midi_fd,0,42,127);
140   sleep(1);
141  }
142
143  close(midi_fd);
144 }
145 #endif TEST_API
146