/*
* Copyright (C) 2005-2007 by Pieter Palmers
*
* This file is part of FFADO
* FFADO = Free Firewire (pro-)audio drivers for linux
*
* FFADO is based upon FreeBoB.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
/**
* Test application for the direct decode stream API
* for floating point use
*/
#ifdef HAVE_CONFIG_H
#include
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "libffado/ffado.h"
#include "debugtools.h"
#define IEC61883_AM824_LABEL_MIDI_NO_DATA 0x80
#define IEC61883_AM824_LABEL_MIDI_1X 0x81
#define IEC61883_AM824_LABEL_MIDI_2X 0x82
#define IEC61883_AM824_LABEL_MIDI_3X 0x83
#define ALSA_SEQ_BUFF_SIZE 1024
#define MAX_MIDI_PORTS 20
#define MIDI_TRANSMIT_BUFFER_SIZE 1024
int run;
static void sighandler (int sig)
{
run = 0;
}
typedef struct {
int seq_port_nr;
snd_midi_event_t *parser;
snd_seq_t *seq_handle;
} ffado_midi_port_t;
typedef struct {
snd_seq_t *seq_handle;
int nb_seq_ports;
ffado_midi_port_t *ports[MAX_MIDI_PORTS];
} ffado_midi_ports_t;
int open_seq(snd_seq_t **seq_handle, int in_ports[], int out_ports[], int num_in, int num_out);
/* Open ALSA sequencer with num_in writeable ports and num_out readable ports. */
/* The sequencer handle and the port IDs are returned. */
int open_seq(snd_seq_t **seq_handle, int in_ports[], int out_ports[], int num_in, int num_out) {
int l1;
char portname[64];
if (snd_seq_open(seq_handle, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK) < 0) {
fprintf(stderr, "Error opening ALSA sequencer.\n");
return(-1);
}
snd_seq_set_client_name(*seq_handle, "FreeBob MIDI I/O test");
for (l1 = 0; l1 < num_in; l1++) {
sprintf(portname, "MIDI OUT %d", l1);
if ((in_ports[l1] = snd_seq_create_simple_port(*seq_handle, portname,
SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
SND_SEQ_PORT_TYPE_MIDI_GENERIC)) < 0) {
fprintf(stderr, "Error creating sequencer port.\n");
return(-1);
}
}
for (l1 = 0; l1 < num_out; l1++) {
sprintf(portname, "MIDI IN %d", l1);
if ((out_ports[l1] = snd_seq_create_simple_port(*seq_handle, portname,
SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ,
SND_SEQ_PORT_TYPE_MIDI_GENERIC)) < 0) {
fprintf(stderr, "Error creating sequencer port.\n");
return(-1);
}
}
return(0);
}
void decode_midi_byte (ffado_midi_port_t *port, int byte) {
snd_seq_event_t ev;
if ((snd_midi_event_encode_byte(port->parser,byte, &ev)) > 0) {
// printf("message ok, sending it to %d\n", port->seq_port_nr);
// a midi message is complete, send it out to ALSA
snd_seq_ev_set_subs(&ev);
snd_seq_ev_set_direct(&ev);
snd_seq_ev_set_source(&ev, port->seq_port_nr);
snd_seq_event_output_direct(port->seq_handle, &ev);
} else {
}
}
int encode_midi_bytes(ffado_midi_port_t *port, unsigned char *byte_buff, int len) {
static int cnt=0;
cnt++;
if (cnt>64) {
*byte_buff=0xFF;
return 1;
}
return 0;
}
int main(int argc, char *argv[])
{
#define PERIOD_SIZE 1024
int samplesread=0, sampleswritten=0;
int nb_in_channels=0, nb_out_channels=0;
int retval=0;
int i=0;
int start_flag = 0;
int nb_periods=0;
ffado_sample_t **audiobuffers_in;
ffado_sample_t **audiobuffers_out;
ffado_sample_t *nullbuffer;
run=1;
printf("Ffado MIDI streaming test application (1)\n");
signal (SIGINT, sighandler);
signal (SIGPIPE, sighandler);
ffado_device_info_t device_info;
ffado_options_t dev_options;
dev_options.sample_rate=48000; // -1 = detect from discovery
dev_options.period_size=PERIOD_SIZE;
dev_options.nb_buffers=3;
dev_options.realtime=0;
dev_options.packetizer_priority=60;
dev_options.verbose=5;
dev_options.slave_mode=0;
dev_options.snoop_mode=0;
ffado_device_t *dev=ffado_streaming_init(device_info, dev_options);
if (!dev) {
fprintf(stderr,"Could not init Ffado Streaming layer\n");
exit(-1);
}
nb_in_channels=ffado_streaming_get_nb_capture_streams(dev);
nb_out_channels=ffado_streaming_get_nb_playback_streams(dev);
int midi_in_nbchannels=0;
int midi_out_nbchannels=0;
/* allocate intermediate buffers */
audiobuffers_in=calloc(nb_in_channels,sizeof(ffado_sample_t *));
audiobuffers_out=calloc(nb_in_channels,sizeof(ffado_sample_t));
for (i=0;iseq_port_nr=in_ports[cnt++];
midi_out_port->seq_handle=seq_handle;
if (snd_midi_event_new ( ALSA_SEQ_BUFF_SIZE, &(midi_out_port->parser)) < 0) {
fprintf(stderr, "ALSA Error: could not init parser for MIDI OUT port %d\n",i);
exit(1); // this too
}
midi_out_portmap[i]=midi_out_port;
}
break;
default: break;
}
}
cnt=0;
for (i=0;iseq_port_nr=out_ports[cnt++];
midi_in_port->seq_handle=seq_handle;
if (snd_midi_event_new ( ALSA_SEQ_BUFF_SIZE, &(midi_in_port->parser)) < 0) {
fprintf(stderr, "ALSA Error: could not init parser for MIDI IN port %d\n",i);
exit(1); // this too
}
midi_in_portmap[i]=midi_in_port;
}
break;
default: break;
}
}
// start the streaming layer
ffado_streaming_prepare(dev);
start_flag = ffado_streaming_start(dev);
fprintf(stderr,"Entering receive loop (%d,%d)\n",nb_in_channels,nb_out_channels);
while(run && start_flag==0) {
retval = ffado_streaming_wait(dev);
if (retval < 0) {
fprintf(stderr,"Xrun\n");
ffado_streaming_reset(dev);
continue;
}
// ffado_streaming_transfer_buffers(dev);
ffado_streaming_transfer_capture_buffers(dev);
ffado_streaming_transfer_playback_buffers(dev);
nb_periods++;
if((nb_periods % 32)==0) {
// fprintf(stderr,"\r%05d periods",nb_periods);
}
for(i=0;i0) {
fprintf(fid_in[i], "---- Period read (%d samples) ----\n",samplesread);
hexDumpToFile(fid_in[i],(unsigned char*)audiobuffers_in[i],samplesread*sizeof(ffado_sample_t));
}
break;
default: break;
}
// fprintf(fid_in[i], "---- Period read (%d samples) ----\n",samplesread);
// hexDumpToFile(fid_in[i],(unsigned char*)buff,samplesread*sizeof(ffado_sample_t));
}
for(i=0;iparser );
free(midi_in_port);
}
}
// free the MIDI to seq parsers and port structures
for(i=0;iparser );
free(midi_out_port);
}
}
return EXIT_SUCCESS;
}