root/trunk/libfreebob/tests/streaming/testmidistreaming1.c

Revision 241, 13.7 kB (checked in by pieterpalmers, 18 years ago)

* configure.ac: Version bump to 1.0.0

* Changed all FreeBob? to FreeBoB
* Removed all .cvsignore
* Added Pieter to AUTHORS
* Updated NEWS and README (release canditate date added)

by Daniel Wagner

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /***************************************************************************
2   Copyright (C) 2005 by Pieter Palmers   *
3                                                                        *
4   This program is free software; you can redistribute it and/or modify  *
5   it under the terms of the GNU General Public License as published by  *
6   the Free Software Foundation; either version 2 of the License, or     *
7   (at your option) any later version.                                   *
8                                                                         *
9   This program is distributed in the hope that it will be useful,       *
10   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12   GNU General Public License for more details.                          *
13                                                                         *
14   You should have received a copy of the GNU General Public License     *
15   along with this program; if not, write to the                         *
16   Free Software Foundation, Inc.,                                       *
17   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
18  ***************************************************************************/
19
20
21 /**
22  * Test application for the direct decode stream API
23  * for floating point use
24  */
25
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #include <signal.h>
35 #include <libiec61883/iec61883.h>
36 #include <stdio.h>
37 #include <sys/select.h>
38 #include <signal.h>
39 #include <string.h>
40 #include <stdlib.h>
41 #include <alsa/asoundlib.h>
42
43 #include "libfreebob/freebob_streaming.h"
44
45 #include "debugtools.h"
46 #define IEC61883_AM824_LABEL_MIDI_NO_DATA 0x80
47 #define IEC61883_AM824_LABEL_MIDI_1X      0x81
48 #define IEC61883_AM824_LABEL_MIDI_2X      0x82
49 #define IEC61883_AM824_LABEL_MIDI_3X      0x83
50        
51 #define ALSA_SEQ_BUFF_SIZE 1024
52 #define MAX_MIDI_PORTS   20
53 #define MIDI_TRANSMIT_BUFFER_SIZE 1024
54
55 int run;
56
57 static void sighandler (int sig)
58 {
59         run = 0;
60 }
61
62 typedef struct {
63         int seq_port_nr;
64         snd_midi_event_t *parser;
65         snd_seq_t *seq_handle;
66 } freebob_midi_port_t;
67
68 typedef struct {
69         snd_seq_t *seq_handle;
70         int nb_seq_ports;
71         freebob_midi_port_t *ports[MAX_MIDI_PORTS];
72 } freebob_midi_ports_t;
73
74 int open_seq(snd_seq_t **seq_handle, int in_ports[], int out_ports[], int num_in, int num_out);
75
76 /* Open ALSA sequencer with num_in writeable ports and num_out readable ports. */
77 /* The sequencer handle and the port IDs are returned.                        */ 
78 int open_seq(snd_seq_t **seq_handle, int in_ports[], int out_ports[], int num_in, int num_out) {
79
80         int l1;
81         char portname[64];
82
83         if (snd_seq_open(seq_handle, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK) < 0) {
84                 fprintf(stderr, "Error opening ALSA sequencer.\n");
85                 return(-1);
86         }
87        
88         snd_seq_set_client_name(*seq_handle, "FreeBoB MIDI I/O test");
89        
90         for (l1 = 0; l1 < num_in; l1++) {
91                 sprintf(portname, "MIDI OUT %d", l1);
92                 if ((in_ports[l1] = snd_seq_create_simple_port(*seq_handle, portname,
93                          SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
94                          SND_SEQ_PORT_TYPE_MIDI_GENERIC)) < 0) {
95                                  fprintf(stderr, "Error creating sequencer port.\n");
96                                  return(-1);
97                          }
98         }
99         for (l1 = 0; l1 < num_out; l1++) {
100                 sprintf(portname, "MIDI IN %d", l1);
101                 if ((out_ports[l1] = snd_seq_create_simple_port(*seq_handle, portname,
102                          SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ,
103                          SND_SEQ_PORT_TYPE_MIDI_GENERIC)) < 0) {
104                                  fprintf(stderr, "Error creating sequencer port.\n");
105                                  return(-1);
106                          }
107         }
108         return(0);
109 }
110
111 void decode_midi_byte (freebob_midi_port_t *port, int byte) {
112         snd_seq_event_t ev;
113         if ((snd_midi_event_encode_byte(port->parser,byte, &ev)) > 0) {
114 //              printf("message ok, sending it to %d\n", port->seq_port_nr);
115                 // a midi message is complete, send it out to ALSA
116                 snd_seq_ev_set_subs(&ev); 
117                 snd_seq_ev_set_direct(&ev);
118                 snd_seq_ev_set_source(&ev, port->seq_port_nr);
119                 snd_seq_event_output_direct(port->seq_handle, &ev);                                             
120         }       else {
121                
122         }
123 }
124
125 int encode_midi_bytes(freebob_midi_port_t *port, unsigned char *byte_buff, int len) {
126         return 0;
127 }
128
129 int main(int argc, char *argv[])
130 {
131
132         #define PERIOD_SIZE 512
133
134         int samplesread=0, sampleswritten=0;
135         int nb_in_channels=0, nb_out_channels=0;
136         int retval=0;
137         int i=0;
138
139         int nb_periods=0;
140
141         freebob_sample_t **audiobuffers_in;
142         freebob_sample_t **audiobuffers_out;
143         freebob_sample_t *nullbuffer;
144        
145         run=1;
146
147         printf("Freebob MIDI streaming test application (1)\n");
148
149         signal (SIGINT, sighandler);
150         signal (SIGPIPE, sighandler);
151
152         freebob_device_info_t device_info;
153
154         freebob_options_t dev_options;
155
156         dev_options.sample_rate=-1; // -1 = detect from discovery
157         dev_options.period_size=PERIOD_SIZE;
158
159         dev_options.nb_buffers=3;
160
161         dev_options.port=1;
162         dev_options.node_id=-1;
163        
164         dev_options.realtime=0;
165         dev_options.packetizer_priority=60;
166        
167         freebob_device_t *dev=freebob_streaming_init(&device_info, dev_options);
168         if (!dev) {
169                 fprintf(stderr,"Could not init Freebob Streaming layer\n");
170                 exit(-1);
171         }
172
173         nb_in_channels=freebob_streaming_get_nb_capture_streams(dev);
174         nb_out_channels=freebob_streaming_get_nb_playback_streams(dev);
175
176         int midi_in_nbchannels=0;
177         int midi_out_nbchannels=0;
178        
179         /* allocate intermediate buffers */
180         audiobuffers_in=calloc(nb_in_channels,sizeof(freebob_sample_t *));
181         audiobuffers_out=calloc(nb_in_channels,sizeof(freebob_sample_t));
182         for (i=0;i<nb_in_channels;i++) {
183                 audiobuffers_in[i]=calloc(PERIOD_SIZE+1,sizeof(freebob_sample_t));
184                 audiobuffers_out[i]=calloc(PERIOD_SIZE+1,sizeof(freebob_sample_t));
185                        
186                 switch (freebob_streaming_get_capture_stream_type(dev,i)) {
187                         case freebob_stream_type_audio:
188                                 /* assign the audiobuffer to the stream */
189                                 freebob_streaming_set_capture_stream_buffer(dev, i, (char *)(audiobuffers_in[i]), freebob_buffer_type_float);
190                                 break;
191                                
192                         // this is done with read/write routines because the nb of bytes can differ.
193                         case freebob_stream_type_midi:
194                                 midi_in_nbchannels++;
195                         default:
196                                 break;
197                 }
198         }
199        
200         nullbuffer=calloc(PERIOD_SIZE+1,sizeof(freebob_sample_t));
201        
202         for (i=0;i<nb_out_channels;i++) {
203                 switch (freebob_streaming_get_capture_stream_type(dev,i)) {
204                         case freebob_stream_type_audio:
205                                 if (i<nb_in_channels) {
206                                         /* assign the audiobuffer to the stream */
207                                         freebob_streaming_set_playback_stream_buffer(dev, i, (char *)audiobuffers_in[i], freebob_buffer_type_float);
208                                 } else {
209                                         freebob_streaming_set_playback_stream_buffer(dev, i, (char *)nullbuffer, freebob_buffer_type_uint24);   
210                                 }
211                                 break;
212                                 // this is done with read/write routines because the nb of bytes can differ.
213                         case freebob_stream_type_midi:
214                                 midi_out_nbchannels++;
215                         default:
216                                 break;
217                 }
218         }
219        
220         /* open the files to write to*/
221         FILE* fid_out[nb_out_channels];
222         FILE* fid_in[nb_in_channels];
223         char name[256];
224
225         for (i=0;i<nb_out_channels;i++) {
226                 snprintf(name,sizeof(name),"out_ch_%02d",i);
227
228                 fid_out[i]=fopen(name,"w");
229
230                 freebob_streaming_get_playback_stream_name(dev,i,name,sizeof(name));
231                 fprintf(fid_out[i],"Channel name: %s\n",name);
232                 switch (freebob_streaming_get_playback_stream_type(dev,i)) {
233                 case freebob_stream_type_audio:
234                         fprintf(fid_out[i],"Channel type: audio\n");
235                         break;
236                 case freebob_stream_type_midi:
237                         fprintf(fid_out[i],"Channel type: midi\n");
238                         break;
239                 case freebob_stream_type_unknown:
240                         fprintf(fid_out[i],"Channel type: unknown\n");
241                         break;
242                 default:
243                 case freebob_stream_type_invalid:
244                         fprintf(fid_out[i],"Channel type: invalid\n");
245                         break;
246                 }
247
248         }
249         for (i=0;i<nb_in_channels;i++) {
250                 snprintf(name,sizeof(name),"in_ch_%02d",i);
251                 fid_in[i]=fopen(name,"w");
252
253                 freebob_streaming_get_capture_stream_name(dev,i,name,sizeof(name));
254                 fprintf(fid_in[i], "Channel name: %s\n");
255                 switch (freebob_streaming_get_capture_stream_type(dev,i)) {
256                 case freebob_stream_type_audio:
257                         fprintf(fid_in[i], "Channel type: audio\n");
258                         break;
259                 case freebob_stream_type_midi:
260                         fprintf(fid_in[i], "Channel type: midi\n");
261                         break;
262                 case freebob_stream_type_unknown:
263                         fprintf(fid_in[i],"Channel type: unknown\n");
264                         break;
265                 default:
266                 case freebob_stream_type_invalid:
267                         fprintf(fid_in[i],"Channel type: invalid\n");
268                         break;
269                 }
270         }
271
272         // setup the ALSA midi seq clients
273         snd_seq_t *seq_handle;
274         int in_ports[midi_in_nbchannels], out_ports[midi_out_nbchannels];
275        
276     // open sequencer
277         // the number of midi ports is statically set to 2
278         if (open_seq(&seq_handle, in_ports, out_ports, midi_in_nbchannels, midi_out_nbchannels) < 0) {
279                 fprintf(stderr, "ALSA Error.\n");
280                 exit(1);
281         }
282
283         freebob_midi_port_t* midi_out_portmap[nb_out_channels];
284         freebob_midi_port_t* midi_in_portmap[nb_in_channels];
285        
286         int cnt=0;
287        
288         for (i=0;i<nb_out_channels;i++) {
289                 freebob_midi_port_t *midi_out_port;
290                 switch (freebob_streaming_get_playback_stream_type(dev,i)) {
291                         case freebob_stream_type_audio:
292                                 midi_out_portmap[i]=NULL;
293                                 break;
294                         case freebob_stream_type_midi:
295                                 midi_out_port=malloc(sizeof(freebob_midi_port_t));
296                                 if(!midi_out_port) {
297                                         fprintf(stderr, "Could not allocate memory for MIDI OUT port %d\n",i);
298                                         exit(1); // this could be/is a memory leak, I know...
299                                 } else {
300                                         midi_out_port->seq_port_nr=in_ports[cnt++];
301                                         midi_out_port->seq_handle=seq_handle;
302                                         if (snd_midi_event_new  ( ALSA_SEQ_BUFF_SIZE, &(midi_out_port->parser)) < 0) {
303                                                 fprintf(stderr, "ALSA Error: could not init parser for MIDI OUT port %d\n",i);
304                                                 exit(1); // this too
305                                         }   
306                                         midi_out_portmap[i]=midi_out_port;
307                                 }
308                                 break;
309                 }
310         }
311        
312         cnt=0;
313         for (i=0;i<nb_in_channels;i++) {
314                 freebob_midi_port_t *midi_in_port;
315                 switch (freebob_streaming_get_capture_stream_type(dev,i)) {
316                         case freebob_stream_type_audio:
317                                 midi_in_portmap[i]=NULL;
318                                 break;
319                         case freebob_stream_type_midi:
320                
321                                 midi_in_port=malloc(sizeof(freebob_midi_port_t));
322                                 if(!midi_in_port) {
323                                         fprintf(stderr, "Could not allocate memory for MIDI IN port %d\n",i);
324                                         exit(1); // this could be/is a memory leak, I know...
325                                 } else {
326                                         midi_in_port->seq_port_nr=out_ports[cnt++];
327                                         midi_in_port->seq_handle=seq_handle;
328                        
329                                         if (snd_midi_event_new  ( ALSA_SEQ_BUFF_SIZE, &(midi_in_port->parser)) < 0) {
330                                                 fprintf(stderr, "ALSA Error: could not init parser for MIDI IN port %d\n",i);
331                                                 exit(1); // this too
332                                         }   
333                                         midi_in_portmap[i]=midi_in_port;
334                                 }
335                         break;
336                 }
337         }       
338        
339         // start the streaming layer
340         freebob_streaming_start(dev);
341
342         fprintf(stderr,"Entering receive loop (%d,%d)\n",nb_in_channels,nb_out_channels);
343         while(run) {
344                 retval = freebob_streaming_wait(dev);
345                 if (retval < 0) {
346                         fprintf(stderr,"Xrun\n");
347                         freebob_streaming_reset(dev);
348                         continue;
349                 }
350                
351 //              freebob_streaming_transfer_buffers(dev);
352                 freebob_streaming_transfer_capture_buffers(dev);
353                 freebob_streaming_transfer_playback_buffers(dev);
354                
355                 nb_periods++;
356
357                 if((nb_periods % 32)==0) {
358 //                      fprintf(stderr,"\r%05d periods",nb_periods);
359                 }
360
361                 for(i=0;i<nb_in_channels;i++) {
362                         int s;
363                        
364                         switch (freebob_streaming_get_capture_stream_type(dev,i)) {
365                         case freebob_stream_type_audio:
366                                 // no need to get the buffers manually, we have set the API internal buffers to the audiobuffer[i]'s
367 //                              //samplesread=freebob_streaming_read(dev, i, audiobuffer[i], PERIOD_SIZE);
368                                 samplesread=PERIOD_SIZE;
369                                 break;
370                         case freebob_stream_type_midi:
371                                 samplesread=freebob_streaming_read(dev, i, audiobuffers_in[i], PERIOD_SIZE);
372                                 quadlet_t *buff=(quadlet_t *)audiobuffers_in[i];
373                                 for (s=0;s<samplesread;s++) {
374                                         quadlet_t *byte=(buff+s) ;
375 //                                      printf("%08X ",*byte);
376                                         decode_midi_byte (midi_in_portmap[i], (*byte) & 0xFF);
377                                 }
378                                 if(samplesread>0) {
379                                         fprintf(fid_in[i], "---- Period read (%d samples) ----\n",samplesread);
380                                         hexDumpToFile(fid_in[i],(unsigned char*)audiobuffers_in[i],samplesread*sizeof(freebob_sample_t));
381                                 }
382                                 break;
383                         }
384 //                      fprintf(fid_in[i], "---- Period read (%d samples) ----\n",samplesread);
385 //                      hexDumpToFile(fid_in[i],(unsigned char*)buff,samplesread*sizeof(freebob_sample_t));
386        
387                 }
388
389                 for(i=0;i<nb_out_channels;i++) {
390                         freebob_sample_t *buff;
391                         int b=0;
392                         unsigned char* byte_buff;
393                        
394                         if (i<nb_in_channels) {
395                                 buff=audiobuffers_out[i];
396                         } else {
397                                 buff=nullbuffer;
398                         }
399                        
400                         switch (freebob_streaming_get_playback_stream_type(dev,i)) {
401                         case freebob_stream_type_audio:
402 //                              sampleswritten=freebob_streaming_write(dev, i, buff, PERIOD_SIZE);
403 //                              sampleswritten=PERIOD_SIZE;
404                                 break;
405                         case freebob_stream_type_midi:
406                                
407                                 #define max_midi_bytes_to_write PERIOD_SIZE/8
408                                 byte_buff=(unsigned char*)buff;
409                                
410                                 sampleswritten=encode_midi_bytes(midi_out_portmap[i], byte_buff, max_midi_bytes_to_write);
411                                
412                                 for(b=0;b<sampleswritten;b++) {
413                                         freebob_sample_t tmp_event=*(byte_buff+b);
414                                         freebob_streaming_write(dev, i, &tmp_event, 1);
415                                 }
416                                
417                                
418                                 fprintf(fid_out[i], "---- Period write (%d samples) ----\n",sampleswritten);
419                                 hexDumpToFile(fid_out[i],(unsigned char*)buff,sampleswritten*sizeof(freebob_sample_t));
420                                 break;
421                         }
422                 }
423
424         }
425
426         fprintf(stderr,"\n");
427
428         fprintf(stderr,"Exiting receive loop\n");
429        
430         freebob_streaming_stop(dev);
431
432         freebob_streaming_finish(dev);
433
434         for (i=0;i<nb_out_channels;i++) {
435                 fclose(fid_out[i]);
436
437         }
438         for (i=0;i<nb_in_channels;i++) {
439                 fclose(fid_in[i]);
440         }
441        
442         for (i=0;i<nb_in_channels;i++) {
443                 free(audiobuffers_in[i]);
444                 free(audiobuffers_out[i]);
445         }
446         free(nullbuffer);
447         free(audiobuffers_in);
448         free(audiobuffers_out);
449        
450         // free the MIDI to seq parsers and port structures
451         for(i=0;i<midi_in_nbchannels;i++) {
452                 freebob_midi_port_t *midi_in_port=midi_in_portmap[i];
453                
454                 if(midi_in_port) {
455                         snd_midi_event_free  (  midi_in_port->parser );
456                         free(midi_in_port);
457                 }
458         }
459         // free the MIDI to seq parsers and port structures
460         for(i=0;i<midi_out_nbchannels;i++) {
461                 freebob_midi_port_t *midi_out_port=midi_out_portmap[i];
462
463                 if(midi_out_port) {
464                         snd_midi_event_free  (  midi_out_port->parser );
465                         free(midi_out_port);
466                 }
467         }
468
469   return EXIT_SUCCESS;
470 }
Note: See TracBrowser for help on using the browser.