Browse Source

clean up the firewire backend a bit

git-svn-id: svn+ssh://jackaudio.org/trunk/jack@3100 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.115.6
pieterpalmers 16 years ago
parent
commit
71674f0cc1
1 changed files with 61 additions and 51 deletions
  1. +61
    -51
      drivers/firewire/ffado_driver.c

+ 61
- 51
drivers/firewire/ffado_driver.c View File

@@ -310,8 +310,8 @@ ffado_driver_detach (ffado_driver_t *driver)
static int
ffado_driver_read (ffado_driver_t * driver, jack_nframes_t nframes)
{
jack_default_audio_sample_t* buf;
channel_t chn;
int nb_connections;
JSList *node;
jack_port_t* port;
@@ -319,21 +319,28 @@ ffado_driver_read (ffado_driver_t * driver, jack_nframes_t nframes)
for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) {
if(driver->capture_channels[chn].stream_type == ffado_stream_type_audio) {
port = (jack_port_t *) node->data;
nb_connections = jack_port_connected (port);

buf = jack_port_get_buffer (port, nframes);
/* if the returned buffer is invalid, use the dummy buffer */
if(!buf) {
buf=(jack_default_audio_sample_t*)driver->scratchbuffer;
/* if there are no connections, use the dummy buffer and disable the stream */
if(nb_connections) {
ffado_streaming_capture_stream_onoff(driver->dev, chn, 1);
ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(jack_port_get_buffer (port, nframes)));
} else {
ffado_streaming_capture_stream_onoff(driver->dev, chn, 0);
ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(driver->scratchbuffer));
}
ffado_streaming_capture_stream_onoff(driver->dev, chn, 1);

ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(buf));
} else if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
port = (jack_port_t *) node->data;
nb_connections = jack_port_connected (port);
if(nb_connections) {
ffado_streaming_capture_stream_onoff(driver->dev, chn, 1);
} else {
ffado_streaming_capture_stream_onoff(driver->dev, chn, 0);
}
/* always set a buffer */
ffado_streaming_set_capture_stream_buffer(driver->dev, chn,
(char *)(driver->capture_channels[chn].midi_buffer));
} else { // always have a valid buffer
} else { /* ensure a valid buffer */
ffado_streaming_set_capture_stream_buffer(driver->dev, chn, (char *)(driver->scratchbuffer));
ffado_streaming_capture_stream_onoff(driver->dev, chn, 0);
}
@@ -345,28 +352,30 @@ ffado_driver_read (ffado_driver_t * driver, jack_nframes_t nframes)
/* process the midi data */
for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) {
if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
jack_default_audio_sample_t* buf;
int i;
int done;
uint32_t *midi_buffer = driver->capture_channels[chn].midi_buffer;
midi_unpack_t *midi_unpack = &driver->capture_channels[chn].midi_unpack;
port = (jack_port_t *) node->data;
nb_connections = jack_port_connected (port);
buf = jack_port_get_buffer (port, nframes);
jack_midi_clear_buffer(buf);

/* if the returned buffer is invalid, discard the midi data */
if(!buf) continue;
jack_midi_clear_buffer(buf);

/* no connections means no processing */
if(nb_connections == 0) continue;

/* else unpack
note that libffado guarantees that midi bytes are on 8-byte aligned indexes
*/
for(i=0; i<nframes; i+=8) {
note that libffado guarantees that midi bytes are on 8-byte aligned indexes */
for(i = 0; i < nframes; i += 8) {
if(midi_buffer[i] & 0xFF000000) {
done=midi_unpack_buf(midi_unpack, (unsigned char *)(midi_buffer+i), 1, buf, i);
done = midi_unpack_buf(midi_unpack, (unsigned char *)(midi_buffer+i), 1, buf, i);
if (done != 1) {
printError("buffer overflow in channel %d\n", chn);
printError("MIDI buffer overflow in channel %d\n", chn);
break;
}
printMessage("MIDI IN: %08X (i=%d)", midi_buffer[i], i);
}
}
}
@@ -380,8 +389,8 @@ static int
ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nframes)
{
channel_t chn;
int nb_connections;
JSList *node;
jack_default_audio_sample_t* buf;
jack_port_t *port;
printEnter();
@@ -393,50 +402,53 @@ ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nframes)
for (chn = 0, node = driver->playback_ports; node; node = jack_slist_next (node), chn++) {
if(driver->playback_channels[chn].stream_type == ffado_stream_type_audio) {
port = (jack_port_t *) node->data;
nb_connections = jack_port_connected (port);

buf = jack_port_get_buffer (port, nframes);
/* use the silent buffer if there is no valid jack buffer */
if(!buf) {
/* use the silent buffer + disable if there are no connections */
if(nb_connections) {
ffado_streaming_playback_stream_onoff(driver->dev, chn, 1);
ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(jack_port_get_buffer (port, nframes)));
} else {
ffado_streaming_playback_stream_onoff(driver->dev, chn, 0);
buf=(jack_default_audio_sample_t*)driver->nullbuffer;
ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(driver->nullbuffer));
}
ffado_streaming_playback_stream_onoff(driver->dev, chn, 1);
ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(buf));
} else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) {
jack_default_audio_sample_t* buf;
int nevents;
int i;
midi_pack_t *midi_pack = &driver->playback_channels[chn].midi_pack;
uint32_t *midi_buffer = driver->playback_channels[chn].midi_buffer;
int min_next_pos=0;
int min_next_pos = 0;

port = (jack_port_t *) node->data;
buf = jack_port_get_buffer (port, nframes);

memset(midi_buffer, 0, nframes * sizeof(uint32_t));
ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(midi_buffer));
nb_connections = jack_port_connected (port);

/* if the returned buffer is invalid, continue */
if(!buf) {
/* skip if no connections */
if(nb_connections == 0) {
ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(driver->nullbuffer));
ffado_streaming_playback_stream_onoff(driver->dev, chn, 0);
continue;
}

memset(midi_buffer, 0, nframes * sizeof(uint32_t));
ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(midi_buffer));
ffado_streaming_playback_stream_onoff(driver->dev, chn, 1);

// check if we still have to process bytes from the previous period
/* check if we still have to process bytes from the previous period */
/*
if(driver->playback_channels[chn].nb_overflow_bytes) {
printMessage("have to process %d bytes from previous period", driver->playback_channels[chn].nb_overflow_bytes);
}
*/
for (i=0; i<driver->playback_channels[chn].nb_overflow_bytes; ++i) {
midi_buffer[min_next_pos] = 0x01000000 | (driver->playback_channels[chn].overflow_buffer[i] & 0xFF);
min_next_pos += 8;
}
driver->playback_channels[chn].nb_overflow_bytes=0;
// process the events in this period
/* process the events in this period */
buf = jack_port_get_buffer (port, nframes);
nevents = jack_midi_get_event_count(buf);
//if (nevents)
// printMessage("MIDI: %d events in ch %d", nevents, chn);

for (i=0; i<nevents; ++i) {
int j;
@@ -444,31 +456,31 @@ ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nframes)
jack_midi_event_get(&event, buf, i);

midi_pack_event(midi_pack, &event);
// floor the initial position to be a multiple of 8
/* floor the initial position to be a multiple of 8 */
int pos = event.time & 0xFFFFFFF8;
for(j = 0; j < event.size; j++) {
// make sure we don't overwrite a previous byte
/* make sure we don't overwrite a previous byte */
while(pos < min_next_pos && pos < nframes) {
printMessage("have to correct pos to %d", pos);
/* printMessage("have to correct pos to %d", pos); */
pos += 8;
}

if(pos >= nframes) {
int f;
printMessage("midi message crosses period boundary");
/* printMessage("midi message crosses period boundary"); */
driver->playback_channels[chn].nb_overflow_bytes = event.size - j;
if(driver->playback_channels[chn].nb_overflow_bytes > MIDI_OVERFLOW_BUFFER_SIZE) {
printError("too much midi bytes cross period boundary");
driver->playback_channels[chn].nb_overflow_bytes = MIDI_OVERFLOW_BUFFER_SIZE;
}
// save the bytes that still have to be transmitted in the next period
for(f=0; f<driver->playback_channels[chn].nb_overflow_bytes; f++) {
/* save the bytes that still have to be transmitted in the next period */
for(f = 0; f < driver->playback_channels[chn].nb_overflow_bytes; f++) {
driver->playback_channels[chn].overflow_buffer[f] = event.buffer[j+f];
}
// exit since we can't transmit anything anymore.
// the rate should be controlled
if(i<nevents-1) {
/* exit since we can't transmit anything anymore.
the rate should be controlled */
if(i < nevents-1) {
printError("%d midi events lost due to period crossing", nevents-i-1);
}
break;
@@ -478,10 +490,8 @@ ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nframes)
min_next_pos = pos;
}
}
//printMessage("MIDI: sent %d-byte event at %ld", (int)event.size, (long)event.time);
}

} else { // always have a valid buffer
} else { /* ensure a valid buffer */
ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(driver->nullbuffer));
ffado_streaming_playback_stream_onoff(driver->dev, chn, 0);
}


Loading…
Cancel
Save