diff --git a/drivers/firewire/ffado_driver.c b/drivers/firewire/ffado_driver.c index 58c5307..bafe6c0 100644 --- a/drivers/firewire/ffado_driver.c +++ b/drivers/firewire/ffado_driver.c @@ -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; iplayback_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; iplayback_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= 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; fplayback_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(idev, chn, (char *)(driver->nullbuffer)); ffado_streaming_playback_stream_onoff(driver->dev, chn, 0); }