-
[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  return(read(fd,buf,1));
72 }
73
74 int midi_read_msg(int fd,char *buf) {
75  char tmp_buf;
76  int i;
77  midi_read(fd,tmp_buf);
78  printf("debug: %x\n",tmp_buf);
79  buf[0]=tmp_buf;
80
81  /* decide how much to read */
82  if(((buf[0]&MSB_MASK)==PROGRAM_CHANGE) || ((buf[0]&MSB_MASK)==CHANNEL_PRESSURE)) {
83   printf("debug: program change or channel pressure event detected\n");
84   midi_read(fd,tmp_buf);
85   buf[1]=tmp_buf;
86   return 2;
87  } else {
88   printf("debug: none program change or channel pressure event detected\n");
89   for(i=0;i<2;i++) {
90    midi_read(fd,tmp_buf);
91    buf[i+1]=tmp_buf;
92   }
93   return 3;
94  }
95 }
96  
97
98
99
100 #ifdef TEST_API
101 /* test the io api ... */
102
103 int main(int argc,char **argv) {
104
105  int note,channel,i,j,k;
106  char my_buf[3];
107
108  if(argc>1) {
109   note=atoi(argv[2]);
110   channel=atoi(argv[1]);
111  }
112
113  midi_fd=open(MIDI_DEVICE,O_RDWR);
114  printf("debug: midi_fd = %d\n",midi_fd);
115
116  printf("reading ...\n");
117  i=midi_read_msg(midi_fd,my_buf);
118  printf("debug: i = %d\n",i);
119  for(k=0;k<i;k++) {
120   for(j=7;j>=0;j--) printf("%s%d%s",(j==7?"|":""),
121                                 (((int)my_buf[k] & (1<<j))>0?1:0),
122                                 (j==0?"|\t":"|"));
123  }
124  printf("\n");
125  printf("sleep for 3 secs ...\n");
126  sleep(3);
127
128  all_stop(midi_fd);
129  sleep(2);
130
131  for(i=0;i<4;i++) {
132   note_off(midi_fd,0,38,127);
133   note_off(midi_fd,0,42,127);
134   note_on(midi_fd,0,42,127);
135   note_on(midi_fd,0,38,127);
136   sleep(1);
137   note_off(midi_fd,0,42,127);
138   note_on(midi_fd,0,42,127);
139   sleep(1);
140  }
141
142  close(midi_fd);
143 }
144 #endif TEST_API
145