along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id$
*/
/* see gdither.cc for why we have to do this */
using namespace PBD;
static int
-convert_spec_to_info (AudioExportSpecification& spec, SF_INFO& sfinfo)
+convert_spec_to_info (ExportSpecification& spec, SF_INFO& sfinfo)
{
if (spec.path.length() == 0) {
error << _("Export: no output file specified") << endmsg;
return 0;
}
-AudioExportSpecification::AudioExportSpecification ()
+ExportSpecification::ExportSpecification ()
{
init ();
}
-AudioExportSpecification::~AudioExportSpecification ()
+ExportSpecification::~ExportSpecification ()
{
clear ();
}
void
-AudioExportSpecification::init ()
+ExportSpecification::init ()
{
src_state = 0;
pos = 0;
}
void
-AudioExportSpecification::clear ()
+ExportSpecification::clear ()
{
if (out) {
sf_close (out);
}
int
-AudioExportSpecification::prepare (jack_nframes_t blocksize, jack_nframes_t frate)
+ExportSpecification::prepare (nframes_t blocksize, nframes_t frate)
{
char errbuf[256];
GDitherSize dither_size;
frame_rate = frate;
if (channels == 0) {
- error << _("illegal frame range in export specification") << endmsg;
+ error << _("illegal channel count in export specification") << endmsg;
return -1;
}
}
src_data.src_ratio = sample_rate / (double) frame_rate;
- out_samples_max = (jack_nframes_t) ceil (blocksize * src_data.src_ratio * channels);
+ out_samples_max = (nframes_t) ceil (blocksize * src_data.src_ratio * channels);
dataF2 = new float[out_samples_max];
max_leftover_frames = 4 * blocksize;
}
int
-AudioExportSpecification::process (jack_nframes_t nframes)
+ExportSpecification::process (nframes_t nframes)
{
float* float_buffer = 0;
uint32_t chn;
uint32_t i;
sf_count_t written;
char errbuf[256];
- jack_nframes_t to_write = 0;
+ nframes_t to_write = 0;
int cnt = 0;
-
+
do {
/* now do sample rate conversion */
break;
}
- if ((jack_nframes_t) written != to_write) {
+ if ((nframes_t) written != to_write) {
sf_error_str (out, errbuf, sizeof (errbuf) - 1);
error << string_compose(_("Export: could not write data to output file (%1)"), errbuf) << endmsg;
return -1;
}
int
-Session::start_audio_export (AudioExportSpecification& spec)
+Session::start_export (ExportSpecification& spec)
{
- int ret;
+ if (!_engine.connected()) {
+ return -1;
+ }
if (spec.prepare (current_block_size, frame_rate())) {
return -1;
spec.pos = spec.start_frame;
spec.end_frame = spec.end_frame;
spec.total_frames = spec.end_frame - spec.start_frame;
+ spec.running = true;
+ spec.do_freewheel = false; /* force a call to ::prepare_to_export() before proceeding to normal operation */
spec.freewheel_connection = _engine.Freewheel.connect (sigc::bind (mem_fun (*this, &Session::process_export), &spec));
- if ((ret = _engine.freewheel (true)) == 0) {
- spec.running = true;
- spec.do_freewheel = false;
- }
-
- return ret;
+ return _engine.freewheel (true);
}
int
-Session::stop_audio_export (AudioExportSpecification& spec)
+Session::stop_export (ExportSpecification& spec)
{
- /* can't use stop_transport() here because we need
- an immediate halt and don't require all the declick
- stuff that stop_transport() implements.
- */
-
- realtime_stop (true);
- schedule_butler_transport_work ();
-
- /* restart slaving */
-
- if (post_export_slave != None) {
- set_slave_source (post_export_slave, post_export_position);
- } else {
- locate (post_export_position, false, false, false);
- }
-
- spec.clear ();
- _exporting = false;
+ /* don't stop freewheeling but do stop paying attention to it for now */
- spec.running = false;
+ spec.freewheel_connection.disconnect ();
+ spec.clear (); /* resets running/stop etc */
return 0;
}
int
-Session::prepare_to_export (AudioExportSpecification& spec)
+Session::prepare_to_export (ExportSpecification& spec)
{
int ret = -1;
/* no slaving */
- post_export_slave = _slave_type;
+ post_export_slave = Config->get_slave_source ();
post_export_position = _transport_frame;
- set_slave_source (None, 0);
+ Config->set_slave_source (None);
/* get transport ready */
}
int
-Session::process_export (jack_nframes_t nframes, AudioExportSpecification* spec)
+Session::process_export (nframes_t nframes, ExportSpecification* spec)
{
uint32_t chn;
uint32_t x;
int ret = -1;
- jack_nframes_t this_nframes;
+ nframes_t this_nframes;
/* This is not required to be RT-safe because we are running while freewheeling */
if (!spec->running || spec->stop || (this_nframes = min ((spec->end_frame - spec->pos), nframes)) == 0) {
process_without_events (nframes);
- return stop_audio_export (*spec);
+ return stop_export (*spec);
}
/* make sure we've caught up with disk i/o, since
for (chn = 0; chn < spec->channels; ++chn) {
- AudioExportPortMap::iterator mi = spec->port_map.find (chn);
+ ExportPortMap::iterator mi = spec->port_map.find (chn);
if (mi == spec->port_map.end()) {
/* no ports exported to this channel */
/* OK, this port's output is supposed to appear on this channel
*/
- AudioPort* const port = dynamic_cast<AudioPort*>((*t).first);
- if (port == 0) {
- cerr << "FIXME: Non-audio export" << endl;
- continue;
- }
- Sample* port_buffer = port->get_audio_buffer().data(nframes);
+ AudioPort* const aport = dynamic_cast<AudioPort*>((*t).first);
+ MidiPort* const mport = dynamic_cast<MidiPort*>((*t).first);
+ if (aport != 0) {
+ Sample* port_buffer = aport->get_audio_buffer().data();
- /* now interleave the data from the channel into the float buffer */
-
- for (x = 0; x < nframes; ++x) {
- spec->dataF[chn+(x*spec->channels)] += (float) port_buffer[x];
+ /* now interleave the data from the channel into the float buffer */
+
+ for (x = 0; x < nframes; ++x) {
+ spec->dataF[chn+(x*spec->channels)] += (float) port_buffer[x];
+ }
+ } else if (mport != 0) {
+ cerr << "EXPORT MIDI PORT" << endl;
}
}
}
return ret;
}
+void
+Session::finalize_audio_export ()
+{
+ _engine.freewheel (false);
+ _exporting = false;
+
+ /* can't use stop_transport() here because we need
+ an immediate halt and don't require all the declick
+ stuff that stop_transport() implements.
+ */
+
+ realtime_stop (true);
+ schedule_butler_transport_work ();
+
+ /* restart slaving */
+
+ if (post_export_slave != None) {
+ Config->set_slave_source (post_export_slave);
+ } else {
+ locate (post_export_position, false, false, false);
+ }
+}