use libsndfile for all audio file i/o, and rename DiskStream AudioDiskStream

git-svn-id: svn://localhost/ardour2/trunk@589 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2006-06-14 21:17:32 +00:00
parent 2387ef8bfb
commit b09ab54654
79 changed files with 1113 additions and 1495 deletions

View file

@ -2,7 +2,7 @@
export ARDOUR_PATH=./glade:./pixmaps:. export ARDOUR_PATH=./glade:./pixmaps:.
export LD_LIBRARY_PATH=../libs/surfaces/control_protocol:../libs/ardour:../libs/midi++2:../libs/pbd3:../libs/soundtouch:../libs/gtkmm2ext:../libs/sigc++2:../libs/glibmm2:../libs/gtkmm2/atk:../libs/gtkmm2/pango:../libs/gtkmm2/gdk:../libs/gtkmm2/gtk:../libs/libgnomecanvasmm:../libs/libglademm:$LD_LIBRARY_PATH export LD_LIBRARY_PATH=../libs/surfaces/control_protocol:../libs/ardour:../libs/midi++2:../libs/pbd3:../libs/soundtouch:../libs/gtkmm2ext:../libs/sigc++2:../libs/glibmm2:../libs/gtkmm2/atk:../libs/gtkmm2/pango:../libs/gtkmm2/gdk:../libs/gtkmm2/gtk:../libs/libgnomecanvasmm:../libs/libsndfile:$LD_LIBRARY_PATH
# DYLD_LIBRARY_PATH is for darwin. # DYLD_LIBRARY_PATH is for darwin.
export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH

View file

@ -207,6 +207,8 @@
<menu action='AudioFileFormatHeader'> <menu action='AudioFileFormatHeader'>
<menuitem action='FileHeaderFormatBWF'/> <menuitem action='FileHeaderFormatBWF'/>
<menuitem action='FileHeaderFormatWAVE'/> <menuitem action='FileHeaderFormatWAVE'/>
<menuitem action='FileHeaderFormatWAVE64'/>
<menuitem action='FileHeaderFormatCAF'/>
</menu> </menu>
</menu> </menu>
<menu action='Autoconnect'> <menu action='Autoconnect'>

View file

@ -50,8 +50,8 @@
#include <ardour/audioengine.h> #include <ardour/audioengine.h>
#include <ardour/playlist.h> #include <ardour/playlist.h>
#include <ardour/utils.h> #include <ardour/utils.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/filesource.h> #include <ardour/audiofilesource.h>
#include <ardour/recent_sessions.h> #include <ardour/recent_sessions.h>
#include <ardour/session_diskstream.h> #include <ardour/session_diskstream.h>
#include <ardour/port.h> #include <ardour/port.h>
@ -184,9 +184,9 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
gettimeofday (&last_peak_grab, 0); gettimeofday (&last_peak_grab, 0);
gettimeofday (&last_shuttle_request, 0); gettimeofday (&last_shuttle_request, 0);
ARDOUR::DiskStream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread)); ARDOUR::AudioDiskstream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
ARDOUR::DiskStream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler)); ARDOUR::AudioDiskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
ARDOUR::DiskStream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler)); ARDOUR::AudioDiskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
/* handle pending state with a dialog */ /* handle pending state with a dialog */
@ -241,10 +241,10 @@ ARDOUR_UI::set_engine (AudioEngine& e)
/* this being a GUI and all, we want peakfiles */ /* this being a GUI and all, we want peakfiles */
FileSource::set_build_peakfiles (true); AudioFileSource::set_build_peakfiles (true);
FileSource::set_build_missing_peakfiles (true); AudioFileSource::set_build_missing_peakfiles (true);
if (Source::start_peak_thread ()) { if (AudioSource::start_peak_thread ()) {
throw failed_constructor(); throw failed_constructor();
} }
@ -281,7 +281,7 @@ ARDOUR_UI::~ARDOUR_UI ()
delete add_route_dialog; delete add_route_dialog;
} }
Source::stop_peak_thread (); AudioSource::stop_peak_thread ();
} }
gint gint
@ -542,7 +542,7 @@ ARDOUR_UI::update_buffer_load ()
} }
void void
ARDOUR_UI::count_recenabled_diskstreams (DiskStream& ds) ARDOUR_UI::count_recenabled_diskstreams (AudioDiskstream& ds)
{ {
if (ds.record_enabled()) { if (ds.record_enabled()) {
rec_enabled_diskstreams++; rec_enabled_diskstreams++;
@ -570,7 +570,7 @@ ARDOUR_UI::update_disk_space()
if (session->actively_recording()){ if (session->actively_recording()){
rec_enabled_diskstreams = 0; rec_enabled_diskstreams = 0;
session->foreach_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams); session->foreach_audio_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams);
if (rec_enabled_diskstreams) { if (rec_enabled_diskstreams) {
frames /= rec_enabled_diskstreams; frames /= rec_enabled_diskstreams;
@ -917,7 +917,7 @@ restart JACK with more ports."));
} }
void void
ARDOUR_UI::diskstream_added (DiskStream* ds) ARDOUR_UI::diskstream_added (AudioDiskstream* ds)
{ {
} }
@ -1164,7 +1164,7 @@ ARDOUR_UI::toggle_monitor_enable (guint32 dstream)
return; return;
} }
DiskStream *ds; AudioDiskstream *ds;
if ((ds = session->diskstream_by_id (dstream)) != 0) { if ((ds = session->diskstream_by_id (dstream)) != 0) {
Port *port = ds->io()->input (0); Port *port = ds->io()->input (0);
@ -1179,7 +1179,7 @@ ARDOUR_UI::toggle_record_enable (guint32 dstream)
return; return;
} }
DiskStream *ds; AudioDiskstream *ds;
if ((ds = session->diskstream_by_id (dstream)) != 0) { if ((ds = session->diskstream_by_id (dstream)) != 0) {
ds->set_record_enabled (!ds->record_enabled(), this); ds->set_record_enabled (!ds->record_enabled(), this);
@ -1386,7 +1386,7 @@ ARDOUR_UI::stop_blinking ()
void void
ARDOUR_UI::add_diskstream_to_menu (DiskStream& dstream) ARDOUR_UI::add_diskstream_to_menu (AudioDiskstream& dstream)
{ {
using namespace Gtk; using namespace Gtk;
using namespace Menu_Helpers; using namespace Menu_Helpers;
@ -1424,7 +1424,7 @@ ARDOUR_UI::select_diskstream (GdkEventButton *ev)
MenuList& items = diskstream_menu->items(); MenuList& items = diskstream_menu->items();
items.push_back (MenuElem (_("No Stream"), (bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), -1)))); items.push_back (MenuElem (_("No Stream"), (bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), -1))));
session->foreach_diskstream (this, &ARDOUR_UI::add_diskstream_to_menu); session->foreach_audio_diskstream (this, &ARDOUR_UI::add_diskstream_to_menu);
if (ev) { if (ev) {
diskstream_menu->popup (ev->button, ev->time); diskstream_menu->popup (ev->button, ev->time);
@ -1569,7 +1569,7 @@ ARDOUR_UI::secondary_clock_value_changed ()
} }
void void
ARDOUR_UI::rec_enable_button_blink (bool onoff, DiskStream *dstream, Widget *w) ARDOUR_UI::rec_enable_button_blink (bool onoff, AudioDiskstream *dstream, Widget *w)
{ {
if (session && dstream && dstream->record_enabled()) { if (session && dstream && dstream->record_enabled()) {
@ -2216,11 +2216,11 @@ ARDOUR_UI::halt_on_xrun_message ()
} }
void void
ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::Source*>* deletion_list) ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::AudioFileSource*>* deletion_list)
{ {
ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list)); ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
for (list<Source*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) { for (list<AudioFileSource*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
delete *i; delete *i;
} }
@ -2377,6 +2377,12 @@ ARDOUR_UI::set_native_file_header_format (HeaderFormat hf)
case RF64: case RF64:
act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64")); act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
break; break;
case CAF:
act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
break;
case AIFF:
act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
break;
} }
if (act) { if (act) {
@ -2451,6 +2457,12 @@ ARDOUR_UI::use_config ()
case RF64: case RF64:
act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64")); act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
break; break;
case CAF:
act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
break;
case AIFF:
act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
break;
} }
if (act) { if (act) {

View file

@ -167,7 +167,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
blinking rec-enable buttons. blinking rec-enable buttons.
*/ */
void rec_enable_button_blink (bool onoff, ARDOUR::DiskStream *, Gtk::Widget *w); void rec_enable_button_blink (bool onoff, ARDOUR::AudioDiskstream *, Gtk::Widget *w);
void name_io_setup (ARDOUR::AudioEngine&, string&, ARDOUR::IO& io, bool in); void name_io_setup (ARDOUR::AudioEngine&, string&, ARDOUR::IO& io, bool in);
void choose_io (ARDOUR::IO&, bool input); void choose_io (ARDOUR::IO&, bool input);
@ -522,7 +522,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
sigc::connection point_one_second_connection; sigc::connection point_one_second_connection;
sigc::connection point_zero_one_second_connection; sigc::connection point_zero_one_second_connection;
void diskstream_added (ARDOUR::DiskStream*); void diskstream_added (ARDOUR::AudioDiskstream*);
gint session_menu (GdkEventButton *); gint session_menu (GdkEventButton *);
@ -539,7 +539,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
void session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode); void session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode);
void add_diskstream_to_menu (ARDOUR::DiskStream&); void add_diskstream_to_menu (ARDOUR::AudioDiskstream&);
void diskstream_selected (gint32); void diskstream_selected (gint32);
Gtk::Menu *diskstream_menu; Gtk::Menu *diskstream_menu;
gint32 selected_dstream; gint32 selected_dstream;
@ -630,7 +630,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
void toggle_monitor_enable (guint32); void toggle_monitor_enable (guint32);
uint32_t rec_enabled_diskstreams; uint32_t rec_enabled_diskstreams;
void count_recenabled_diskstreams (ARDOUR::DiskStream&); void count_recenabled_diskstreams (ARDOUR::AudioDiskstream&);
About* about; About* about;
bool shown_flag; bool shown_flag;
@ -649,7 +649,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
struct timeval last_peak_grab; struct timeval last_peak_grab;
struct timeval last_shuttle_request; struct timeval last_shuttle_request;
void delete_sources_in_the_right_thread (list<ARDOUR::Source*>*); void delete_sources_in_the_right_thread (list<ARDOUR::AudioFileSource*>*);
void editor_display_control_changed (Editing::DisplayControl c); void editor_display_control_changed (Editing::DisplayControl c);

View file

@ -75,8 +75,8 @@ ARDOUR_UI::connect_to_session (Session *s)
rec_button.set_sensitive (true); rec_button.set_sensitive (true);
shuttle_box.set_sensitive (true); shuttle_box.set_sensitive (true);
if (session->n_diskstreams() == 0) { if (session->n_audio_diskstreams() == 0) {
session->DiskStreamAdded.connect (mem_fun(*this, &ARDOUR_UI::diskstream_added)); session->AudioDiskstreamAdded.connect (mem_fun(*this, &ARDOUR_UI::diskstream_added));
} }
if (connection_editor) { if (connection_editor) {

View file

@ -381,8 +381,9 @@ ARDOUR_UI::install_actions ()
act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatBWF"), X_("Broadcast WAVE"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::BWF)); act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatBWF"), X_("Broadcast WAVE"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::BWF));
act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatWAVE"), X_("WAVE"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::WAVE)); act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatWAVE"), X_("WAVE"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::WAVE));
act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatWAVE64"), X_("WAVE-64"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::WAVE64)); act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatWAVE64"), X_("WAVE-64"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::WAVE64));
act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatiXML"), X_("iXML"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::iXML)); // act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatiXML"), X_("iXML"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::iXML));
act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatRF64"), X_("RF64"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::RF64)); // act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatRF64"), X_("RF64"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::RF64));
act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatCAF"), X_("CAF"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::CAF));
RadioAction::Group file_data_group; RadioAction::Group file_data_group;

View file

@ -195,6 +195,8 @@ AudioClock::AudioClock (const string& name, bool allow_edit, bool duration, bool
clock_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK); clock_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK);
clock_base.signal_button_release_event().connect (bind (mem_fun (*this, &AudioClock::field_button_release_event), SMPTE_Hours)); clock_base.signal_button_release_event().connect (bind (mem_fun (*this, &AudioClock::field_button_release_event), SMPTE_Hours));
Session::SMPTEOffsetChanged.connect (mem_fun (*this, &AudioClock::smpte_offset_changed));
if (editable) { if (editable) {
setup_events (); setup_events ();
} }
@ -389,6 +391,25 @@ AudioClock::set (jack_nframes_t when, bool force)
last_when = when; last_when = when;
} }
void
AudioClock::smpte_offset_changed ()
{
jack_nframes_t current;
switch (_mode) {
case SMPTE:
if (is_duration) {
current = current_duration();
} else {
current = current_time ();
}
set (current, true);
break;
default:
break;
}
}
void void
AudioClock::set_frames (jack_nframes_t when, bool force) AudioClock::set_frames (jack_nframes_t when, bool force)
{ {
@ -446,9 +467,9 @@ AudioClock::set_smpte (jack_nframes_t when, bool force)
if (force || smpte.hours != last_hrs || smpte.negative != last_negative) { if (force || smpte.hours != last_hrs || smpte.negative != last_negative) {
if (smpte.negative) { if (smpte.negative) {
sprintf (buf, "-%02ld", smpte.hours); sprintf (buf, "-%02" PRIu32, smpte.hours);
} else { } else {
sprintf (buf, " %02ld", smpte.hours); sprintf (buf, " %02" PRIu32, smpte.hours);
} }
hours_label.set_text (buf); hours_label.set_text (buf);
last_hrs = smpte.hours; last_hrs = smpte.hours;
@ -456,19 +477,19 @@ AudioClock::set_smpte (jack_nframes_t when, bool force)
} }
if (force || smpte.minutes != last_mins) { if (force || smpte.minutes != last_mins) {
sprintf (buf, "%02ld", smpte.minutes); sprintf (buf, "%02" PRIu32, smpte.minutes);
minutes_label.set_text (buf); minutes_label.set_text (buf);
last_mins = smpte.minutes; last_mins = smpte.minutes;
} }
if (force || smpte.seconds != last_secs) { if (force || smpte.seconds != last_secs) {
sprintf (buf, "%02ld", smpte.seconds); sprintf (buf, "%02" PRIu32, smpte.seconds);
seconds_label.set_text (buf); seconds_label.set_text (buf);
last_secs = smpte.seconds; last_secs = smpte.seconds;
} }
if (force || smpte.frames != last_frames) { if (force || smpte.frames != last_frames) {
sprintf (buf, "%02ld", smpte.frames); sprintf (buf, "%02" PRIu32, smpte.frames);
frames_label.set_text (buf); frames_label.set_text (buf);
last_frames = smpte.frames; last_frames = smpte.frames;
} }
@ -1267,7 +1288,7 @@ AudioClock::smpte_frame_from_display () const
smpte.minutes = atoi (minutes_label.get_text()); smpte.minutes = atoi (minutes_label.get_text());
smpte.seconds = atoi (seconds_label.get_text()); smpte.seconds = atoi (seconds_label.get_text());
smpte.frames = atoi (frames_label.get_text()); smpte.frames = atoi (frames_label.get_text());
session->smpte_to_sample( smpte, sample, false /* use_offset */, false /* use_subframes */ ); session->smpte_to_sample( smpte, sample, false /* use_offset */, false /* use_subframes */ );

View file

@ -175,6 +175,8 @@ class AudioClock : public Gtk::HBox
void build_ops_menu (); void build_ops_menu ();
void setup_events (); void setup_events ();
void smpte_offset_changed ();
static const uint32_t field_length[(int)AudioFrames+1]; static const uint32_t field_length[(int)AudioFrames+1];
}; };

View file

@ -38,7 +38,7 @@
#include <gtkmm2ext/utils.h> #include <gtkmm2ext/utils.h>
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/insert.h> #include <ardour/insert.h>
#include <ardour/ladspa_plugin.h> #include <ardour/ladspa_plugin.h>
#include <ardour/location.h> #include <ardour/location.h>
@ -823,7 +823,7 @@ AudioTimeAxisView::rename_current_playlist ()
string name; string name;
AudioPlaylist *pl; AudioPlaylist *pl;
DiskStream *ds; AudioDiskstream *ds;
if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) { if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) {
return; return;
@ -851,7 +851,7 @@ void
AudioTimeAxisView::use_copy_playlist (bool prompt) AudioTimeAxisView::use_copy_playlist (bool prompt)
{ {
AudioPlaylist *pl; AudioPlaylist *pl;
DiskStream *ds; AudioDiskstream *ds;
string name; string name;
if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) { if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) {
@ -891,7 +891,7 @@ void
AudioTimeAxisView::use_new_playlist (bool prompt) AudioTimeAxisView::use_new_playlist (bool prompt)
{ {
AudioPlaylist *pl; AudioPlaylist *pl;
DiskStream *ds; AudioDiskstream *ds;
string name; string name;
if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) { if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) {
@ -930,7 +930,7 @@ void
AudioTimeAxisView::clear_playlist () AudioTimeAxisView::clear_playlist ()
{ {
AudioPlaylist *pl; AudioPlaylist *pl;
DiskStream *ds; AudioDiskstream *ds;
if ((ds = get_diskstream()) != 0) { if ((ds = get_diskstream()) != 0) {
if ((pl = ds->playlist()) != 0) { if ((pl = ds->playlist()) != 0) {
@ -988,7 +988,7 @@ AudioTimeAxisView::diskstream_changed (void *src)
void void
AudioTimeAxisView::update_diskstream_display () AudioTimeAxisView::update_diskstream_display ()
{ {
DiskStream *ds; AudioDiskstream *ds;
if ((ds = get_diskstream()) != 0) { if ((ds = get_diskstream()) != 0) {
set_playlist (ds->playlist ()); set_playlist (ds->playlist ());
@ -1092,7 +1092,7 @@ AudioTimeAxisView::name() const
Playlist * Playlist *
AudioTimeAxisView::playlist () const AudioTimeAxisView::playlist () const
{ {
DiskStream *ds; AudioDiskstream *ds;
if ((ds = get_diskstream()) != 0) { if ((ds = get_diskstream()) != 0) {
return ds->playlist(); return ds->playlist();
@ -1142,7 +1142,7 @@ AudioTimeAxisView::hide_click ()
Region* Region*
AudioTimeAxisView::find_next_region (jack_nframes_t pos, RegionPoint point, int32_t dir) AudioTimeAxisView::find_next_region (jack_nframes_t pos, RegionPoint point, int32_t dir)
{ {
DiskStream *stream; AudioDiskstream *stream;
AudioPlaylist *playlist; AudioPlaylist *playlist;
if ((stream = get_diskstream()) != 0 && (playlist = stream->playlist()) != 0) { if ((stream = get_diskstream()) != 0 && (playlist = stream->playlist()) != 0) {
@ -1717,7 +1717,7 @@ bool
AudioTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op) AudioTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
{ {
Playlist* what_we_got; Playlist* what_we_got;
DiskStream* ds = get_diskstream(); AudioDiskstream* ds = get_diskstream();
Playlist* playlist; Playlist* playlist;
bool ret = false; bool ret = false;

View file

@ -48,7 +48,7 @@ namespace ALSA {
namespace ARDOUR { namespace ARDOUR {
class Session; class Session;
class DiskStream; class AudioDiskstream;
class RouteGroup; class RouteGroup;
class Redirect; class Redirect;
class Insert; class Insert;

View file

@ -34,6 +34,7 @@
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/auditioner.h> #include <ardour/auditioner.h>
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
#include <ardour/audiosource.h>
#include <ardour/playlist_templates.h> #include <ardour/playlist_templates.h>
#include <gtkmm2ext/gtk_ui.h> #include <gtkmm2ext/gtk_ui.h>

View file

@ -38,7 +38,7 @@
#include <gtkmm2ext/utils.h> #include <gtkmm2ext/utils.h>
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/plugin_manager.h> #include <ardour/plugin_manager.h>
#include <ardour/location.h> #include <ardour/location.h>
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
@ -1636,7 +1636,7 @@ Editor::build_track_region_context_menu (jack_nframes_t frame)
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (clicked_trackview); AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (clicked_trackview);
if (atv) { if (atv) {
DiskStream* ds; AudioDiskstream* ds;
Playlist* pl; Playlist* pl;
if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) { if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) {
@ -1663,7 +1663,7 @@ Editor::build_track_crossfade_context_menu (jack_nframes_t frame)
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (clicked_trackview); AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (clicked_trackview);
if (atv) { if (atv) {
DiskStream* ds; AudioDiskstream* ds;
Playlist* pl; Playlist* pl;
AudioPlaylist* apl; AudioPlaylist* apl;
@ -3107,7 +3107,7 @@ Editor::mapped_set_selected_regionview_from_click (AudioTimeAxisView& atv, uint3
AudioPlaylist* pl; AudioPlaylist* pl;
vector<AudioRegion*> results; vector<AudioRegion*> results;
AudioRegionView* marv; AudioRegionView* marv;
DiskStream* ds; AudioDiskstream* ds;
if ((ds = atv.get_diskstream()) == 0) { if ((ds = atv.get_diskstream()) == 0) {
/* bus */ /* bus */
@ -3338,7 +3338,7 @@ Editor::set_selected_regionview_from_region_list (Region& r, Selection::Operatio
AudioPlaylist* pl; AudioPlaylist* pl;
vector<AudioRegion*> results; vector<AudioRegion*> results;
AudioRegionView* marv; AudioRegionView* marv;
DiskStream* ds; AudioDiskstream* ds;
if ((ds = tatv->get_diskstream()) == 0) { if ((ds = tatv->get_diskstream()) == 0) {
/* bus */ /* bus */

View file

@ -45,7 +45,6 @@
#include <ardour/tempo.h> #include <ardour/tempo.h>
#include <ardour/location.h> #include <ardour/location.h>
#include <ardour/region.h> #include <ardour/region.h>
#include <ardour/externalsource.h>
#include "audio_clock.h" #include "audio_clock.h"
#include "gtk-custom-ruler.h" #include "gtk-custom-ruler.h"
@ -67,9 +66,8 @@ namespace LinuxAudioSystems {
} }
namespace ARDOUR { namespace ARDOUR {
class DiskStream; class AudioDiskstream;
class RouteGroup; class RouteGroup;
class Source;
class Playlist; class Playlist;
class Region; class Region;
class Location; class Location;

View file

@ -26,12 +26,11 @@
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/filesource.h>
#include <ardour/externalsource.h>
#include <ardour/utils.h> #include <ardour/utils.h>
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
#include <ardour/audiofilesource.h>
#include "ardour_ui.h" #include "ardour_ui.h"
#include "editor.h" #include "editor.h"
@ -187,7 +186,7 @@ int
Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool& check_sample_rate, ImportMode mode, Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool& check_sample_rate, ImportMode mode,
AudioTrack* track, jack_nframes_t& pos, bool prompt) AudioTrack* track, jack_nframes_t& pos, bool prompt)
{ {
ExternalSource *source = 0; /* keep g++ quiet */ AudioFileSource *source = 0; /* keep g++ quiet */
AudioRegion::SourceList sources; AudioRegion::SourceList sources;
AudioRegion* region; AudioRegion* region;
string idspec; string idspec;
@ -220,7 +219,7 @@ Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool
string error_msg; string error_msg;
if (!ExternalSource::get_soundfile_info (path, finfo, error_msg)) { if (!AudioFileSource::get_soundfile_info (path, finfo, error_msg)) {
error << string_compose(_("Editor: cannot open file \"%1\", (%2)"), selection, error_msg ) << endmsg; error << string_compose(_("Editor: cannot open file \"%1\", (%2)"), selection, error_msg ) << endmsg;
return 0; return 0;
} }
@ -267,7 +266,7 @@ Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool
idspec += string_compose(":%1", n); idspec += string_compose(":%1", n);
try { try {
source = ExternalSource::create (idspec.c_str()); source = AudioFileSource::create (idspec.c_str());
sources.push_back(source); sources.push_back(source);
} }

View file

@ -1,5 +1,5 @@
#include <ardour/location.h> #include <ardour/location.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include "editor.h" #include "editor.h"
#include "editing.h" #include "editing.h"

View file

@ -21,7 +21,7 @@
#include <cstdlib> #include <cstdlib>
#include <cmath> #include <cmath>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
#include "editor.h" #include "editor.h"

View file

@ -37,8 +37,8 @@
#include <ardour/types.h> #include <ardour/types.h>
#include <ardour/export.h> #include <ardour/export.h>
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include <ardour/filesource.h> #include <ardour/audiofilesource.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
@ -154,7 +154,7 @@ Editor::bounce_region_selection ()
bool bool
Editor::write_region (string path, AudioRegion& region) Editor::write_region (string path, AudioRegion& region)
{ {
FileSource* fs; AudioFileSource* fs;
const jack_nframes_t chunk_size = 4096; const jack_nframes_t chunk_size = 4096;
jack_nframes_t to_read; jack_nframes_t to_read;
Sample buf[chunk_size]; Sample buf[chunk_size];
@ -163,7 +163,7 @@ Editor::write_region (string path, AudioRegion& region)
jack_nframes_t pos; jack_nframes_t pos;
char s[PATH_MAX+1]; char s[PATH_MAX+1];
uint32_t cnt; uint32_t cnt;
vector<FileSource *> sources; vector<AudioFileSource *> sources;
uint32_t nchans; uint32_t nchans;
nchans = region.n_channels(); nchans = region.n_channels();
@ -204,7 +204,7 @@ Editor::write_region (string path, AudioRegion& region)
try { try {
fs = new FileSource (path, session->frame_rate()); fs = AudioFileSource::create (path);
} }
catch (failed_constructor& err) { catch (failed_constructor& err) {
@ -227,10 +227,10 @@ Editor::write_region (string path, AudioRegion& region)
this_time = min (to_read, chunk_size); this_time = min (to_read, chunk_size);
for (vector<FileSource *>::iterator src=sources.begin(); src != sources.end(); ++src) { for (vector<AudioFileSource *>::iterator src=sources.begin(); src != sources.end(); ++src) {
fs = (*src);
fs = (*src);
if (region.read_at (buf, buf, gain_buffer, workbuf, pos, this_time) != this_time) { if (region.read_at (buf, buf, gain_buffer, workbuf, pos, this_time) != this_time) {
break; break;
} }
@ -250,7 +250,7 @@ Editor::write_region (string path, AudioRegion& region)
time (&tnow); time (&tnow);
now = localtime (&tnow); now = localtime (&tnow);
for (vector<FileSource *>::iterator src = sources.begin(); src != sources.end(); ++src) { for (vector<AudioFileSource *>::iterator src = sources.begin(); src != sources.end(); ++src) {
(*src)->update_header (0, *now, tnow); (*src)->update_header (0, *now, tnow);
} }
@ -258,7 +258,8 @@ Editor::write_region (string path, AudioRegion& region)
error_out: error_out:
for (vector<FileSource*>::iterator i = sources.begin(); i != sources.end(); ++i) { for (vector<AudioFileSource*>::iterator i = sources.begin(); i != sources.end(); ++i) {
(*i)->mark_for_remove (); (*i)->mark_for_remove ();
delete (*i); delete (*i);
} }
@ -300,7 +301,7 @@ Editor::write_audio_selection (TimeSelection& ts)
bool bool
Editor::write_audio_range (Playlist& playlist, uint32_t channels, list<AudioRange>& range) Editor::write_audio_range (Playlist& playlist, uint32_t channels, list<AudioRange>& range)
{ {
FileSource* fs; AudioFileSource* fs;
const jack_nframes_t chunk_size = 4096; const jack_nframes_t chunk_size = 4096;
jack_nframes_t nframes; jack_nframes_t nframes;
Sample buf[chunk_size]; Sample buf[chunk_size];
@ -310,7 +311,7 @@ Editor::write_audio_range (Playlist& playlist, uint32_t channels, list<AudioRang
char s[PATH_MAX+1]; char s[PATH_MAX+1];
uint32_t cnt; uint32_t cnt;
string path; string path;
vector<FileSource *> sources; vector<AudioFileSource *> sources;
for (uint32_t n=0; n < channels; ++n) { for (uint32_t n=0; n < channels; ++n) {
@ -337,7 +338,7 @@ Editor::write_audio_range (Playlist& playlist, uint32_t channels, list<AudioRang
path = s; path = s;
try { try {
fs = new FileSource (path, session->frame_rate()); fs = AudioFileSource::create (path);
} }
catch (failed_constructor& err) { catch (failed_constructor& err) {
@ -420,7 +421,7 @@ Editor::write_audio_range (Playlist& playlist, uint32_t channels, list<AudioRang
error_out: error_out:
/* unref created files */ /* unref created files */
for (vector<FileSource*>::iterator i = sources.begin(); i != sources.end(); ++i) { for (vector<AudioFileSource*>::iterator i = sources.begin(); i != sources.end(); ++i) {
(*i)->mark_for_remove (); (*i)->mark_for_remove ();
delete *i; delete *i;
} }

View file

@ -47,7 +47,7 @@
#include <ardour/types.h> #include <ardour/types.h>
#include <ardour/route.h> #include <ardour/route.h>
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/playlist.h> #include <ardour/playlist.h>
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>
@ -286,7 +286,7 @@ Editor::step_mouse_mode (bool next)
void void
Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type) Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
{ {
bool commit; bool commit = false;
bool c1; bool c1;
bool c2; bool c2;

View file

@ -36,9 +36,7 @@
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/filesource.h>
#include <ardour/externalsource.h>
#include <ardour/utils.h> #include <ardour/utils.h>
#include <ardour/location.h> #include <ardour/location.h>
#include <ardour/named_selection.h> #include <ardour/named_selection.h>
@ -122,9 +120,9 @@ Editor::set_meter_hold (int32_t cnt)
void void
Editor::set_meter_falloff (int intval) Editor::set_meter_falloff (int intval)
{ {
float val; float val = 0.0f; /* off */
std::string str; std::string str;
cerr << "set_meter_falloff () called: intval = " << intval << endl;
Config->set_meter_falloff_off(false); Config->set_meter_falloff_off(false);
Config->set_meter_falloff_slowest(false); Config->set_meter_falloff_slowest(false);
Config->set_meter_falloff_slow(false); Config->set_meter_falloff_slow(false);

View file

@ -26,6 +26,7 @@
#include <pbd/basename.h> #include <pbd/basename.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>
#include <ardour/audiosource.h>
#include <ardour/session_region.h> #include <ardour/session_region.h>
#include <gtkmm2ext/stop_signal.h> #include <gtkmm2ext/stop_signal.h>

View file

@ -36,7 +36,7 @@
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include "i18n.h" #include "i18n.h"

View file

@ -31,7 +31,7 @@
#include <ardour/port.h> #include <ardour/port.h>
#include <ardour/insert.h> #include <ardour/insert.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <gtkmm2ext/doi.h> #include <gtkmm2ext/doi.h>
#include <gtkmm2ext/gtk_ui.h> #include <gtkmm2ext/gtk_ui.h>

View file

@ -458,7 +458,6 @@ main (int argc, char *argv[])
ui = 0; ui = 0;
} }
out:
delete engine; delete engine;
ARDOUR::cleanup (); ARDOUR::cleanup ();
shutdown (0); shutdown (0);

View file

@ -20,7 +20,7 @@
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/session_route.h> #include <ardour/session_route.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include "ardour_ui.h" #include "ardour_ui.h"

View file

@ -37,7 +37,7 @@
#include <ardour/audioengine.h> #include <ardour/audioengine.h>
#include <ardour/route.h> #include <ardour/route.h>
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/panner.h> #include <ardour/panner.h>
#include <ardour/send.h> #include <ardour/send.h>
#include <ardour/insert.h> #include <ardour/insert.h>
@ -665,9 +665,9 @@ MixerStrip::select_stream_input ()
MenuList& items = stream_menu->items(); MenuList& items = stream_menu->items();
stream_menu->set_name ("ArdourContextMenu"); stream_menu->set_name ("ArdourContextMenu");
Session::DiskStreamList streams = _session.disk_streams(); Session::AudioDiskstreamList streams = _session.audio_disk_streams();
for (Session::DiskStreamList::iterator i = streams.begin(); i != streams.end(); ++i) { for (Session::AudioDiskstreamList::iterator i = streams.begin(); i != streams.end(); ++i) {
if (!(*i)->hidden()) { if (!(*i)->hidden()) {
@ -685,7 +685,7 @@ MixerStrip::select_stream_input ()
} }
void void
MixerStrip::stream_input_chosen (DiskStream *stream) MixerStrip::stream_input_chosen (AudioDiskstream *stream)
{ {
if (is_audio_track()) { if (is_audio_track()) {
audio_track()->set_diskstream (*stream, this); audio_track()->set_diskstream (*stream, this);

View file

@ -170,7 +170,7 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
Gtk::Menu output_menu; Gtk::Menu output_menu;
void add_connection_to_output_menu (ARDOUR::Connection *); void add_connection_to_output_menu (ARDOUR::Connection *);
void stream_input_chosen (ARDOUR::DiskStream*); void stream_input_chosen (ARDOUR::AudioDiskstream*);
void select_stream_input (); void select_stream_input ();
void connection_input_chosen (ARDOUR::Connection *); void connection_input_chosen (ARDOUR::Connection *);
void connection_output_chosen (ARDOUR::Connection *); void connection_output_chosen (ARDOUR::Connection *);

View file

@ -34,7 +34,7 @@
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include <ardour/session_route.h> #include <ardour/session_route.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/plugin_manager.h> #include <ardour/plugin_manager.h>
#include "mixer_ui.h" #include "mixer_ui.h"

View file

@ -45,7 +45,7 @@ namespace ARDOUR {
class Route; class Route;
class RouteGroup; class RouteGroup;
class Session; class Session;
class DiskStream; class AudioDiskstream;
class AudioEngine; class AudioEngine;
}; };

View file

@ -83,7 +83,7 @@ GTK_ARDOUR::parse_opts (int argc, char *argv[])
{ "name", 1, 0, 'c' }, { "name", 1, 0, 'c' },
{ "novst", 0, 0, 'V' }, { "novst", 0, 0, 'V' },
{ "new", 1, 0, 'N' }, { "new", 1, 0, 'N' },
{ "use-hw-optimizations", 0, 0, 'o' }, { "no-hw-optimizations", 0, 0, 'O' },
{ "curvetest", 1, 0, 'C' }, { "curvetest", 1, 0, 'C' },
{ "gtktheme", 0, 0, 'g' }, { "gtktheme", 0, 0, 'g' },
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
@ -124,8 +124,8 @@ GTK_ARDOUR::parse_opts (int argc, char *argv[])
session_name = optarg; session_name = optarg;
break; break;
case 'o': case 'O':
try_hw_optimization = true; try_hw_optimization = false;
break; break;
case 'V': case 'V':

View file

@ -22,7 +22,7 @@
#include <gtkmm/button.h> #include <gtkmm/button.h>
#include <ardour/session_playlist.h> #include <ardour/session_playlist.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/playlist.h> #include <ardour/playlist.h>
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
@ -89,7 +89,7 @@ void
PlaylistSelector::show_for (RouteUI* ruix) PlaylistSelector::show_for (RouteUI* ruix)
{ {
vector<const char*> item; vector<const char*> item;
DiskStream* this_ds; AudioDiskstream* this_ds;
string str; string str;
rui = ruix; rui = ruix;
@ -115,7 +115,7 @@ PlaylistSelector::show_for (RouteUI* ruix)
for (DSPL_Map::iterator x = dspl_map.begin(); x != dspl_map.end(); ++x) { for (DSPL_Map::iterator x = dspl_map.begin(); x != dspl_map.end(); ++x) {
DiskStream* ds = session->diskstream_by_id (x->first); AudioDiskstream* ds = session->diskstream_by_id (x->first);
if (ds == 0) { if (ds == 0) {
continue; continue;

View file

@ -38,7 +38,7 @@
#include <ardour/audioengine.h> #include <ardour/audioengine.h>
#include <ardour/route.h> #include <ardour/route.h>
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/send.h> #include <ardour/send.h>
#include <ardour/insert.h> #include <ardour/insert.h>
#include <ardour/ladspa_plugin.h> #include <ardour/ladspa_plugin.h>

View file

@ -27,7 +27,8 @@
#include <ardour/playlist.h> #include <ardour/playlist.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>
#include <ardour/diskstream.h> #include <ardour/audiosource.h>
#include <ardour/audio_diskstream.h>
#include "streamview.h" #include "streamview.h"
#include "regionview.h" #include "regionview.h"

View file

@ -26,7 +26,7 @@
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/session_route.h> #include <ardour/session_route.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/plugin.h> #include <ardour/plugin.h>
#include <ardour/plugin_manager.h> #include <ardour/plugin_manager.h>
#include <ardour/ardour.h> #include <ardour/ardour.h>

View file

@ -34,7 +34,7 @@
#include <ardour/route.h> #include <ardour/route.h>
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include "i18n.h" #include "i18n.h"
using namespace sigc; using namespace sigc;
@ -433,7 +433,13 @@ RouteUI::refresh_remote_control_menu ()
limit += 4; /* leave some breathing room */ limit += 4; /* leave some breathing room */
for (uint32_t i = 0; i < limit; ++i) { rc_items.push_back (RadioMenuElem (rc_group, _("None")));
if (_route.remote_control_id() == 0) {
rc_active = dynamic_cast<CheckMenuItem*> (&rc_items.back());
rc_active->set_active ();
}
for (uint32_t i = 1; i < limit; ++i) {
snprintf (buf, sizeof (buf), "%u", i); snprintf (buf, sizeof (buf), "%u", i);
rc_items.push_back (RadioMenuElem (rc_group, buf)); rc_items.push_back (RadioMenuElem (rc_group, buf));
rc_active = dynamic_cast<RadioMenuItem*>(&rc_items.back()); rc_active = dynamic_cast<RadioMenuItem*>(&rc_items.back());
@ -872,7 +878,7 @@ RouteUI::is_audio_track () const
return dynamic_cast<AudioTrack*>(&_route) != 0; return dynamic_cast<AudioTrack*>(&_route) != 0;
} }
DiskStream* AudioDiskstream*
RouteUI::get_diskstream () const RouteUI::get_diskstream () const
{ {
AudioTrack *at; AudioTrack *at;

View file

@ -50,7 +50,7 @@ class RouteUI : public virtual AxisView
virtual ~RouteUI(); virtual ~RouteUI();
bool is_audio_track() const; bool is_audio_track() const;
ARDOUR::DiskStream* get_diskstream() const; ARDOUR::AudioDiskstream* get_diskstream() const;
ARDOUR::Route& route() const { return _route; } ARDOUR::Route& route() const { return _route; }
ARDOUR::AudioTrack* audio_track() const; ARDOUR::AudioTrack* audio_track() const;
@ -116,7 +116,7 @@ class RouteUI : public virtual AxisView
sigc::connection blink_connection; sigc::connection blink_connection;
void rec_enable_button_blink (bool onoff, ARDOUR::DiskStream *, Gtk::Widget *w); void rec_enable_button_blink (bool onoff, ARDOUR::AudioDiskstream *, Gtk::Widget *w);
void remove_this_route (); void remove_this_route ();
static gint idle_remove_this_route (RouteUI *); static gint idle_remove_this_route (RouteUI *);

View file

@ -31,7 +31,7 @@
#include <ardour/audio_library.h> #include <ardour/audio_library.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>
#include <ardour/externalsource.h> #include <ardour/audiofilesource.h>
#include "ardour_ui.h" #include "ardour_ui.h"
#include "gui_thread.h" #include "gui_thread.h"
@ -122,7 +122,7 @@ SoundFileBox::setup_labels (string filename)
path = filename; path = filename;
string error_msg; string error_msg;
if(!ExternalSource::get_soundfile_info (filename, sf_info, error_msg)) { if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
return false; return false;
} }
@ -187,12 +187,12 @@ SoundFileBox::play_btn_clicked ()
if (region_cache.find (path) == region_cache.end()) { if (region_cache.find (path) == region_cache.end()) {
AudioRegion::SourceList srclist; AudioRegion::SourceList srclist;
ExternalSource* sfs; AudioFileSource* afs;
for (int n = 0; n < sf_info.channels; ++n) { for (int n = 0; n < sf_info.channels; ++n) {
try { try {
sfs = ExternalSource::create (path+":"+string_compose("%1", n), false); afs = AudioFileSource::create (path+":"+string_compose("%1", n));
srclist.push_back(sfs); srclist.push_back(afs);
} catch (failed_constructor& err) { } catch (failed_constructor& err) {
error << _("Could not access soundfile: ") << path << endmsg; error << _("Could not access soundfile: ") << path << endmsg;

View file

@ -40,7 +40,7 @@
#include <gtkmm/treeview.h> #include <gtkmm/treeview.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/externalsource.h> #include <ardour/audiofilesource.h>
#include "ardour_dialog.h" #include "ardour_dialog.h"
#include "editing.h" #include "editing.h"
@ -69,7 +69,7 @@ class SoundFileBox : public Gtk::VBox
LabelModelColumns label_columns; LabelModelColumns label_columns;
ARDOUR::SoundFileInfo sf_info; ARDOUR::SoundFileInfo sf_info;
pid_t current_pid; pid_t current_pid;

View file

@ -6,7 +6,8 @@
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>
#include <ardour/diskstream.h> #include <ardour/audiosource.h>
#include <ardour/audio_diskstream.h>
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include <ardour/playlist_templates.h> #include <ardour/playlist_templates.h>
#include <ardour/source.h> #include <ardour/source.h>
@ -311,7 +312,7 @@ StreamView::undisplay_diskstream ()
} }
void void
StreamView::display_diskstream (DiskStream *ds) StreamView::display_diskstream (AudioDiskstream *ds)
{ {
playlist_change_connection.disconnect(); playlist_change_connection.disconnect();
playlist_changed (ds); playlist_changed (ds);
@ -337,7 +338,7 @@ StreamView::playlist_modified ()
} }
void void
StreamView::playlist_changed (DiskStream *ds) StreamView::playlist_changed (AudioDiskstream *ds)
{ {
ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::playlist_changed), ds)); ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::playlist_changed), ds));
@ -491,7 +492,7 @@ StreamView::diskstream_changed (void *src_ignored)
AudioTrack *at; AudioTrack *at;
if ((at = _trackview.audio_track()) != 0) { if ((at = _trackview.audio_track()) != 0) {
DiskStream& ds = at->disk_stream(); AudioDiskstream& ds = at->disk_stream();
/* XXX grrr: when will SigC++ allow me to bind references? */ /* XXX grrr: when will SigC++ allow me to bind references? */
Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun (*this, &StreamView::display_diskstream), &ds)); Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun (*this, &StreamView::display_diskstream), &ds));
} else { } else {
@ -634,7 +635,7 @@ StreamView::setup_rec_box ()
peak_ready_connections.clear(); peak_ready_connections.clear();
for (uint32_t n=0; n < _trackview.get_diskstream()->n_channels(); ++n) { for (uint32_t n=0; n < _trackview.get_diskstream()->n_channels(); ++n) {
Source *src = (Source *) _trackview.get_diskstream()->write_source (n); AudioSource *src = (AudioSource *) _trackview.get_diskstream()->write_source (n);
if (src) { if (src) {
sources.push_back (src); sources.push_back (src);
peak_ready_connections.push_back (src->PeakRangeReady.connect (bind (mem_fun (*this, &StreamView::rec_peak_range_ready), src))); peak_ready_connections.push_back (src->PeakRangeReady.connect (bind (mem_fun (*this, &StreamView::rec_peak_range_ready), src)));
@ -662,7 +663,7 @@ StreamView::setup_rec_box ()
AudioTrack* at; AudioTrack* at;
at = _trackview.audio_track(); /* we know what it is already */ at = _trackview.audio_track(); /* we know what it is already */
DiskStream& ds = at->disk_stream(); AudioDiskstream& ds = at->disk_stream();
jack_nframes_t frame_pos = ds.current_capture_start (); jack_nframes_t frame_pos = ds.current_capture_start ();
gdouble xstart = _trackview.editor.frame_to_pixel (frame_pos); gdouble xstart = _trackview.editor.frame_to_pixel (frame_pos);
gdouble xend; gdouble xend;

View file

@ -37,7 +37,7 @@ namespace Gdk {
namespace ARDOUR { namespace ARDOUR {
class Route; class Route;
class DiskStream; class AudioDiskstream;
class Crossfade; class Crossfade;
class PeakData; class PeakData;
class AudioRegion; class AudioRegion;
@ -151,12 +151,12 @@ class StreamView : public sigc::trackable
void remove_audio_region_view (ARDOUR::AudioRegion* ); void remove_audio_region_view (ARDOUR::AudioRegion* );
void remove_audio_rec_region (ARDOUR::AudioRegion*); void remove_audio_rec_region (ARDOUR::AudioRegion*);
void display_diskstream (ARDOUR::DiskStream* ); void display_diskstream (ARDOUR::AudioDiskstream* );
void undisplay_diskstream (); void undisplay_diskstream ();
void redisplay_diskstream (); void redisplay_diskstream ();
void diskstream_changed (void* ); void diskstream_changed (void* );
void playlist_state_changed (ARDOUR::Change); void playlist_state_changed (ARDOUR::Change);
void playlist_changed (ARDOUR::DiskStream* ); void playlist_changed (ARDOUR::AudioDiskstream* );
void playlist_modified (); void playlist_modified ();
bool crossfades_visible; bool crossfades_visible;

View file

@ -27,7 +27,8 @@
#include <ardour/playlist.h> #include <ardour/playlist.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>
#include <ardour/diskstream.h> #include <ardour/audiosource.h>
#include <ardour/audio_diskstream.h>
#include "taperegionview.h" #include "taperegionview.h"
#include "audio_time_axis.h" #include "audio_time_axis.h"

View file

@ -27,12 +27,15 @@ ardour.Append(POTFILE = domain + '.pot')
ardour.Append(CPPPATH = '#libs/surfaces/control_protocol') ardour.Append(CPPPATH = '#libs/surfaces/control_protocol')
ardour_files=Split(""" ardour_files=Split("""
audio_diskstream.cc
audio_library.cc audio_library.cc
audio_playlist.cc audio_playlist.cc
audio_track.cc audio_track.cc
audioengine.cc audioengine.cc
audiofilesource.cc
audiofilter.cc audiofilter.cc
audioregion.cc audioregion.cc
audiosource.cc
auditioner.cc auditioner.cc
automation.cc automation.cc
automation_event.cc automation_event.cc
@ -44,9 +47,6 @@ curve.cc
cycle_timer.cc cycle_timer.cc
default_click.cc default_click.cc
destructive_filesource.cc destructive_filesource.cc
diskstream.cc
externalsource.cc
filesource.cc
gain.cc gain.cc
gdither.cc gdither.cc
globals.cc globals.cc

View file

@ -26,7 +26,7 @@
namespace ARDOUR { namespace ARDOUR {
class Session; class Session;
class DiskStream; class AudioDiskstream;
class AudioPlaylist; class AudioPlaylist;
class RouteGroup; class RouteGroup;
@ -52,8 +52,8 @@ class AudioTrack : public Route
bool can_record() const { return true; } bool can_record() const { return true; }
void set_record_enable (bool yn, void *src); void set_record_enable (bool yn, void *src);
DiskStream& disk_stream() const { return *diskstream; } AudioDiskstream& disk_stream() const { return *diskstream; }
int set_diskstream (DiskStream&, void *); int set_diskstream (AudioDiskstream&, void *);
int use_diskstream (string name); int use_diskstream (string name);
int use_diskstream (id_t id); int use_diskstream (id_t id);
@ -99,7 +99,7 @@ class AudioTrack : public Route
void set_meter_point (MeterPoint, void* src); void set_meter_point (MeterPoint, void* src);
protected: protected:
DiskStream *diskstream; AudioDiskstream *diskstream;
MeterPoint _saved_meter_point; MeterPoint _saved_meter_point;
TrackMode _mode; TrackMode _mode;

View file

@ -28,7 +28,6 @@ namespace ARDOUR {
class AudioRegion; class AudioRegion;
class Session; class Session;
class FileSource;
class AudioFilter { class AudioFilter {
@ -37,7 +36,6 @@ class AudioFilter {
: session (s){} : session (s){}
virtual ~AudioFilter() {} virtual ~AudioFilter() {}
virtual int run (ARDOUR::AudioRegion&) = 0; virtual int run (ARDOUR::AudioRegion&) = 0;
std::vector<ARDOUR::AudioRegion*> results; std::vector<ARDOUR::AudioRegion*> results;

View file

@ -27,7 +27,6 @@
#include <pbd/undo.h> #include <pbd/undo.h>
#include <ardour/ardour.h> #include <ardour/ardour.h>
#include <ardour/source.h>
#include <ardour/gain.h> #include <ardour/gain.h>
#include <ardour/region.h> #include <ardour/region.h>
#include <ardour/export.h> #include <ardour/export.h>
@ -40,6 +39,7 @@ class Route;
class Playlist; class Playlist;
class Session; class Session;
class AudioFilter; class AudioFilter;
class AudioSource;
struct AudioRegionState : public RegionState struct AudioRegionState : public RegionState
{ {
@ -56,7 +56,7 @@ struct AudioRegionState : public RegionState
class AudioRegion : public Region class AudioRegion : public Region
{ {
public: public:
typedef vector<Source *> SourceList; typedef vector<AudioSource *> SourceList;
static Change FadeInChanged; static Change FadeInChanged;
static Change FadeOutChanged; static Change FadeOutChanged;
@ -66,12 +66,12 @@ class AudioRegion : public Region
static Change ScaleAmplitudeChanged; static Change ScaleAmplitudeChanged;
static Change EnvelopeChanged; static Change EnvelopeChanged;
AudioRegion (Source&, jack_nframes_t start, jack_nframes_t length, bool announce = true); AudioRegion (AudioSource&, jack_nframes_t start, jack_nframes_t length, bool announce = true);
AudioRegion (Source&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true); AudioRegion (AudioSource&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
AudioRegion (SourceList &, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true); AudioRegion (SourceList &, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
AudioRegion (const AudioRegion&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true); AudioRegion (const AudioRegion&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
AudioRegion (const AudioRegion&); AudioRegion (const AudioRegion&);
AudioRegion (Source&, const XMLNode&); AudioRegion (AudioSource&, const XMLNode&);
AudioRegion (SourceList &, const XMLNode&); AudioRegion (SourceList &, const XMLNode&);
~AudioRegion(); ~AudioRegion();
@ -85,7 +85,7 @@ class AudioRegion : public Region
void lock_sources (); void lock_sources ();
void unlock_sources (); void unlock_sources ();
Source& source (uint32_t n=0) const { if (n < sources.size()) return *sources[n]; else return *sources[0]; } AudioSource& source (uint32_t n=0) const { if (n < sources.size()) return *sources[n]; else return *sources[0]; }
void set_scale_amplitude (gain_t); void set_scale_amplitude (gain_t);
gain_t scale_amplitude() const { return _scale_amplitude; } gain_t scale_amplitude() const { return _scale_amplitude; }

View file

@ -31,8 +31,11 @@ class CoreAudioSource : public ExternalSource {
CoreAudioSource (const XMLNode&); CoreAudioSource (const XMLNode&);
~CoreAudioSource (); ~CoreAudioSource ();
jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
float sample_rate() const; float sample_rate() const;
int update_header (jack_nframes_t when, struct tm&, time_t);
protected:
jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
private: private:
ExtAudioFileRef af; ExtAudioFileRef af;

View file

@ -22,29 +22,27 @@
#define __ardour_cycle_timer_h__ #define __ardour_cycle_timer_h__
#include <string> #include <string>
#include <cstdio> #include <iostream>
#include <ardour/cycles.h> #include <ardour/cycles.h>
using std::string;
class CycleTimer { class CycleTimer {
private: private:
static float cycles_per_usec; static float cycles_per_usec;
uint32_t long entry; cycles_t _entry;
uint32_t long exit; cycles_t _exit;
string _name; std::string _name;
public: public:
CycleTimer(string name) : _name (name){ CycleTimer(std::string name) : _name (name){
if (cycles_per_usec == 0) { if (cycles_per_usec == 0) {
cycles_per_usec = get_mhz (); cycles_per_usec = get_mhz ();
} }
entry = get_cycles(); _entry = get_cycles();
} }
~CycleTimer() { ~CycleTimer() {
exit = get_cycles(); _exit = get_cycles();
printf ("%s: %.9f usecs (%lu-%lu)\n", _name.c_str(), (float) (exit - entry) / cycles_per_usec, entry, exit); std::cerr << _name << ": " << (float) (_exit - _entry) / cycles_per_usec << " (" << _entry << ", " << _exit << ')' << endl;
} }
static float get_mhz (); static float get_mhz ();

View file

@ -23,30 +23,33 @@
#include <string> #include <string>
#include <ardour/filesource.h> #include <ardour/sndfilesource.h>
struct tm; struct tm;
namespace ARDOUR { namespace ARDOUR {
class DestructiveFileSource : public FileSource { class DestructiveFileSource : public SndFileSource {
public: public:
DestructiveFileSource (std::string path, jack_nframes_t rate, bool repair_first = false, SampleFormat samp_format=FormatInt24); DestructiveFileSource (std::string path, SampleFormat samp_format, HeaderFormat hdr_format, jack_nframes_t rate,
DestructiveFileSource (const XMLNode&, jack_nframes_t rate); Flag flags = AudioFileSource::Flag (AudioFileSource::Writable|
AudioFileSource::BuildPeaks));
DestructiveFileSource (const XMLNode&);
~DestructiveFileSource (); ~DestructiveFileSource ();
int seek (jack_nframes_t frame);
jack_nframes_t last_capture_start_frame() const; jack_nframes_t last_capture_start_frame() const;
void mark_capture_start (jack_nframes_t); void mark_capture_start (jack_nframes_t);
void mark_capture_end (); void mark_capture_end ();
void clear_capture_marks(); void clear_capture_marks();
jack_nframes_t write (Sample *src, jack_nframes_t cnt, char * workbuf);
XMLNode& get_state (); XMLNode& get_state ();
static void setup_standard_crossfades (jack_nframes_t sample_rate); static void setup_standard_crossfades (jack_nframes_t sample_rate);
protected:
jack_nframes_t write_unlocked (Sample *src, jack_nframes_t start, jack_nframes_t cnt, char * workbuf);
private: private:
static jack_nframes_t xfade_frames; static jack_nframes_t xfade_frames;
static gain_t* out_coefficient; static gain_t* out_coefficient;
@ -59,7 +62,7 @@ class DestructiveFileSource : public FileSource {
Sample* xfade_buf; Sample* xfade_buf;
jack_nframes_t crossfade (Sample* data, jack_nframes_t cnt, int dir, char * workbuf); jack_nframes_t crossfade (Sample* data, jack_nframes_t cnt, int dir, char * workbuf);
void set_timeline_position (jack_nframes_t);
}; };
} }

View file

@ -37,7 +37,6 @@
#include <ardour/crossfade_compare.h> #include <ardour/crossfade_compare.h>
#include <ardour/location.h> #include <ardour/location.h>
#include <ardour/stateful.h> #include <ardour/stateful.h>
#include <ardour/source.h>
#include <ardour/state_manager.h> #include <ardour/state_manager.h>
namespace ARDOUR { namespace ARDOUR {

View file

@ -60,11 +60,12 @@ namespace ARDOUR {
class Port; class Port;
class AudioEngine; class AudioEngine;
class Slave; class Slave;
class DiskStream; class AudioDiskstream;
class Route; class Route;
class AuxInput; class AuxInput;
class Source; class Source;
class FileSource; class AudioSource;
class AudioFileSource;
class Auditioner; class Auditioner;
class Insert; class Insert;
class Send; class Send;
@ -261,25 +262,30 @@ class Session : public sigc::trackable, public Stateful
vector<Sample*>& get_silent_buffers (uint32_t howmany); vector<Sample*>& get_silent_buffers (uint32_t howmany);
vector<Sample*>& get_send_buffers () { return _send_buffers; } vector<Sample*>& get_send_buffers () { return _send_buffers; }
DiskStream *diskstream_by_id (id_t id); AudioDiskstream *diskstream_by_id (id_t id);
DiskStream *diskstream_by_name (string name); AudioDiskstream *diskstream_by_name (string name);
bool have_captured() const { return _have_captured; } bool have_captured() const { return _have_captured; }
void refill_all_diskstream_buffers (); void refill_all_diskstream_buffers ();
uint32_t diskstream_buffer_size() const { return dstream_buffer_size; } uint32_t diskstream_buffer_size() const { return dstream_buffer_size; }
uint32_t get_next_diskstream_id() const { return n_diskstreams(); }
uint32_t n_diskstreams() const;
typedef list<DiskStream *> DiskStreamList; /* XXX fix required here when we get new diskstream types *, but
not sure of the direction to take this in until then.
*/
Session::DiskStreamList disk_streams() const { uint32_t get_next_diskstream_id() const { return n_audio_diskstreams(); }
uint32_t n_audio_diskstreams() const;
typedef list<AudioDiskstream *> AudioDiskstreamList;
Session::AudioDiskstreamList audio_disk_streams() const {
Glib::RWLock::ReaderLock lm (diskstream_lock); Glib::RWLock::ReaderLock lm (diskstream_lock);
return diskstreams; /* XXX yes, force a copy */ return audio_diskstreams; /* XXX yes, force a copy */
} }
void foreach_diskstream (void (DiskStream::*func)(void)); void foreach_audio_diskstream (void (AudioDiskstream::*func)(void));
template<class T> void foreach_diskstream (T *obj, void (T::*func)(DiskStream&)); template<class T> void foreach_audio_diskstream (T *obj, void (T::*func)(AudioDiskstream&));
typedef list<Route *> RouteList; typedef list<Route *> RouteList;
@ -344,7 +350,7 @@ class Session : public sigc::trackable, public Stateful
sigc::signal<void> HaltOnXrun; sigc::signal<void> HaltOnXrun;
sigc::signal<void,Route*> RouteAdded; sigc::signal<void,Route*> RouteAdded;
sigc::signal<void,DiskStream*> DiskStreamAdded; sigc::signal<void,AudioDiskstream*> AudioDiskstreamAdded;
void request_roll (); void request_roll ();
void request_bounded_roll (jack_nframes_t start, jack_nframes_t end); void request_bounded_roll (jack_nframes_t start, jack_nframes_t end);
@ -356,15 +362,15 @@ class Session : public sigc::trackable, public Stateful
void goto_start () { request_locate (start_location->start(), false); } void goto_start () { request_locate (start_location->start(), false); }
void use_rf_shuttle_speed (); void use_rf_shuttle_speed ();
void request_transport_speed (float speed); void request_transport_speed (float speed);
void request_overwrite_buffer (DiskStream*); void request_overwrite_buffer (AudioDiskstream*);
void request_diskstream_speed (DiskStream&, float speed); void request_diskstream_speed (AudioDiskstream&, float speed);
void request_input_change_handling (); void request_input_change_handling ();
bool locate_pending() const { return static_cast<bool>(post_transport_work&PostTransportLocate); } bool locate_pending() const { return static_cast<bool>(post_transport_work&PostTransportLocate); }
bool transport_locked () const; bool transport_locked () const;
int wipe (); int wipe ();
int wipe_diskstream (DiskStream *); int wipe_diskstream (AudioDiskstream *);
int remove_region_from_region_list (Region&); int remove_region_from_region_list (Region&);
@ -612,7 +618,7 @@ class Session : public sigc::trackable, public Stateful
jack_nframes_t convert_to_frames_at (jack_nframes_t position, AnyTime&); jack_nframes_t convert_to_frames_at (jack_nframes_t position, AnyTime&);
sigc::signal<void> SMPTEOffsetChanged; static sigc::signal<void> SMPTEOffsetChanged;
sigc::signal<void> SMPTETypeChanged; sigc::signal<void> SMPTETypeChanged;
void request_slave_source (SlaveSource, jack_nframes_t pos = 0); void request_slave_source (SlaveSource, jack_nframes_t pos = 0);
@ -668,8 +674,9 @@ class Session : public sigc::trackable, public Stateful
int start_audio_export (ARDOUR::AudioExportSpecification&); int start_audio_export (ARDOUR::AudioExportSpecification&);
int stop_audio_export (ARDOUR::AudioExportSpecification&); int stop_audio_export (ARDOUR::AudioExportSpecification&);
void add_source (Source *); void add_audio_source (AudioSource *);
int remove_file_source (FileSource&); void remove_source (Source *);
int cleanup_audio_file_source (AudioFileSource&);
struct cleanup_report { struct cleanup_report {
vector<string> paths; vector<string> paths;
@ -701,7 +708,8 @@ class Session : public sigc::trackable, public Stateful
sigc::signal<void,Source *> SourceAdded; sigc::signal<void,Source *> SourceAdded;
sigc::signal<void,Source *> SourceRemoved; sigc::signal<void,Source *> SourceRemoved;
FileSource *create_file_source (ARDOUR::DiskStream&, int32_t chan, bool destructive); AudioFileSource *create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive);
Source *get_source (ARDOUR::id_t); Source *get_source (ARDOUR::id_t);
/* playlist management */ /* playlist management */
@ -745,8 +753,8 @@ class Session : public sigc::trackable, public Stateful
/* flattening stuff */ /* flattening stuff */
int write_one_track (AudioTrack&, jack_nframes_t start, jack_nframes_t cnt, bool overwrite, vector<Source*>&, int write_one_audio_track (AudioTrack&, jack_nframes_t start, jack_nframes_t cnt, bool overwrite, vector<AudioSource*>&,
InterThreadInfo& wot); InterThreadInfo& wot);
int freeze (InterThreadInfo&); int freeze (InterThreadInfo&);
/* session-wide solo/mute/rec-enable */ /* session-wide solo/mute/rec-enable */
@ -972,7 +980,7 @@ class Session : public sigc::trackable, public Stateful
void set_frame_rate (jack_nframes_t nframes); void set_frame_rate (jack_nframes_t nframes);
protected: protected:
friend class DiskStream; friend class AudioDiskstream;
void stop_butler (); void stop_butler ();
void wait_till_butler_finished(); void wait_till_butler_finished();
@ -1434,12 +1442,12 @@ class Session : public sigc::trackable, public Stateful
bool waiting_to_start; bool waiting_to_start;
void set_auto_loop (bool yn); void set_auto_loop (bool yn);
void overwrite_some_buffers (DiskStream*); void overwrite_some_buffers (AudioDiskstream*);
void flush_all_redirects (); void flush_all_redirects ();
void locate (jack_nframes_t, bool with_roll, bool with_flush, bool with_loop=false); void locate (jack_nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
void start_locate (jack_nframes_t, bool with_roll, bool with_flush, bool with_loop=false); void start_locate (jack_nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
void force_locate (jack_nframes_t frame, bool with_roll = false); void force_locate (jack_nframes_t frame, bool with_roll = false);
void set_diskstream_speed (DiskStream*, float speed); void set_diskstream_speed (AudioDiskstream*, float speed);
void set_transport_speed (float speed, bool abort = false); void set_transport_speed (float speed, bool abort = false);
void stop_transport (bool abort = false); void stop_transport (bool abort = false);
void start_transport (); void start_transport ();
@ -1470,10 +1478,10 @@ class Session : public sigc::trackable, public Stateful
/* disk-streams */ /* disk-streams */
DiskStreamList diskstreams; AudioDiskstreamList audio_diskstreams;
mutable Glib::RWLock diskstream_lock; mutable Glib::RWLock diskstream_lock;
uint32_t dstream_buffer_size; uint32_t dstream_buffer_size;
void add_diskstream (DiskStream*); void add_diskstream (AudioDiskstream*);
int load_diskstreams (const XMLNode&); int load_diskstreams (const XMLNode&);
/* routes stuff */ /* routes stuff */
@ -1515,16 +1523,14 @@ class Session : public sigc::trackable, public Stateful
/* SOURCES */ /* SOURCES */
mutable Glib::Mutex source_lock; mutable Glib::Mutex audio_source_lock;
typedef std::map<id_t, Source *> SourceList; typedef std::map<id_t, AudioSource *> AudioSourceList;
SourceList sources; AudioSourceList audio_sources;
int load_sources (const XMLNode& node); int load_sources (const XMLNode& node);
XMLNode& get_sources_as_xml (); XMLNode& get_sources_as_xml ();
void remove_source (Source *);
Source *XMLSourceFactory (const XMLNode&); Source *XMLSourceFactory (const XMLNode&);
/* PLAYLISTS */ /* PLAYLISTS */
@ -1543,7 +1549,7 @@ class Session : public sigc::trackable, public Stateful
Playlist *XMLPlaylistFactory (const XMLNode&); Playlist *XMLPlaylistFactory (const XMLNode&);
void playlist_length_changed (Playlist *); void playlist_length_changed (Playlist *);
void diskstream_playlist_changed (DiskStream *); void diskstream_playlist_changed (AudioDiskstream *);
/* NAMED SELECTIONS */ /* NAMED SELECTIONS */

View file

@ -22,15 +22,15 @@
#define __ardour_session_diskstream_h__ #define __ardour_session_diskstream_h__
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
namespace ARDOUR { namespace ARDOUR {
template<class T> void template<class T> void
Session::foreach_diskstream (T *obj, void (T::*func)(DiskStream&)) Session::foreach_audio_diskstream (T *obj, void (T::*func)(AudioDiskstream&))
{ {
Glib::RWLock::ReaderLock lm (diskstream_lock); Glib::RWLock::ReaderLock lm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); i++) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); i++) {
if (!(*i)->hidden()) { if (!(*i)->hidden()) {
(obj->*func) (**i); (obj->*func) (**i);
} }

View file

@ -23,29 +23,57 @@
#include <sndfile.h> #include <sndfile.h>
#include <ardour/externalsource.h> #include <ardour/audiofilesource.h>
namespace ARDOUR { namespace ARDOUR {
class SndFileSource : public ExternalSource { class SndFileSource : public AudioFileSource {
public: public:
SndFileSource (const string& path_plus_channel, bool build_peak = true); /* constructor to be called for existing external-to-session files */
SndFileSource (std::string path, Flag flags);
/* constructor to be called for new in-session files */
SndFileSource (std::string path, SampleFormat samp_format, HeaderFormat hdr_format, jack_nframes_t rate,
Flag flags = AudioFileSource::Flag (AudioFileSource::Writable|
AudioFileSource::Removable|
AudioFileSource::RemovableIfEmpty|
AudioFileSource::CanRename|
AudioFileSource::BuildPeaks));
/* constructor to be called for existing in-session files */
SndFileSource (const XMLNode&); SndFileSource (const XMLNode&);
~SndFileSource (); ~SndFileSource ();
jack_nframes_t length() const { return _info.frames; }
jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
float sample_rate () const; float sample_rate () const;
int update_header (jack_nframes_t when, struct tm&, time_t);
int flush_header ();
static Flag default_in_session_flags();
protected:
void set_header_timeline_position ();
jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
jack_nframes_t write_unlocked (Sample *dst, jack_nframes_t cnt, char * workbuf);
jack_nframes_t write_float (Sample* data, jack_nframes_t pos, jack_nframes_t cnt);
private: private:
SNDFILE *sf; SNDFILE *sf;
SF_INFO _info; SF_INFO _info;
SF_BROADCAST_INFO* _broadcast_info;
mutable float *tmpbuf; mutable float *interleave_buf;
mutable jack_nframes_t tmpbufsize; mutable jack_nframes_t interleave_bufsize;
mutable Glib::Mutex _tmpbuf_lock;
void init (const string &str, bool build_peak); void init (const string &str);
int open();
void close();
int setup_broadcast_info (jack_nframes_t when, struct tm&, time_t);
}; };
}; /* namespace ARDOUR */ }; /* namespace ARDOUR */

View file

@ -21,166 +21,46 @@
#ifndef __ardour_source_h__ #ifndef __ardour_source_h__
#define __ardour_source_h__ #define __ardour_source_h__
#include <list>
#include <vector>
#include <string> #include <string>
#include <ctime>
#include <sigc++/signal.h> #include <sigc++/signal.h>
#include <glibmm/thread.h>
#include <ardour/ardour.h> #include <ardour/ardour.h>
#include <ardour/stateful.h> #include <ardour/stateful.h>
#include <pbd/xml++.h>
using std::list;
using std::vector;
using std::string;
namespace ARDOUR { namespace ARDOUR {
struct PeakData {
typedef Sample PeakDatum;
PeakDatum min;
PeakDatum max;
};
const jack_nframes_t frames_per_peak = 256;
class Source : public Stateful, public sigc::trackable class Source : public Stateful, public sigc::trackable
{ {
public: public:
Source (bool announce=true); Source (std::string name);
Source (const XMLNode&); Source (const XMLNode&);
virtual ~Source (); virtual ~Source ();
const string& name() const { return _name; } std::string name() const { return _name; }
int set_name (std::string str, bool destructive);
ARDOUR::id_t id() const { return _id; } ARDOUR::id_t id() const { return _id; }
/* returns the number of items in this `source' */
virtual jack_nframes_t length() const {
return _length;
}
virtual jack_nframes_t available_peaks (double zoom) const;
virtual jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const {
return 0;
}
virtual jack_nframes_t write (Sample *src, jack_nframes_t cnt, char * workbuf) {
return 0;
}
virtual float sample_rate () const { return 0; }
uint32_t use_cnt() const { return _use_cnt; } uint32_t use_cnt() const { return _use_cnt; }
void use (); void use ();
void release (); void release ();
virtual void mark_for_remove() = 0;
virtual void mark_streaming_write_completed () {}
time_t timestamp() const { return _timestamp; } time_t timestamp() const { return _timestamp; }
void stamp (time_t when) { _timestamp = when; } void stamp (time_t when) { _timestamp = when; }
void set_captured_for (string str) { _captured_for = str; }
string captured_for() const { return _captured_for; }
uint32_t read_data_count() const { return _read_data_count; }
uint32_t write_data_count() const { return _write_data_count; }
int read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start, jack_nframes_t cnt, double samples_per_unit) const;
int build_peaks ();
bool peaks_ready (sigc::slot<void>, sigc::connection&) const;
static sigc::signal<void,Source*> SourceCreated;
sigc::signal<void,Source *> GoingAway;
mutable sigc::signal<void> PeaksReady;
mutable sigc::signal<void,jack_nframes_t,jack_nframes_t> PeakRangeReady;
XMLNode& get_state (); XMLNode& get_state ();
int set_state (const XMLNode&); int set_state (const XMLNode&);
static int start_peak_thread (); sigc::signal<void,Source *> GoingAway;
static void stop_peak_thread ();
int rename_peakfile (std::string newpath);
static void set_build_missing_peakfiles (bool yn) {
_build_missing_peakfiles = yn;
}
static void set_build_peakfiles (bool yn) {
_build_peakfiles = yn;
}
protected: protected:
static bool _build_missing_peakfiles;
static bool _build_peakfiles;
string _name; string _name;
uint32_t _use_cnt; uint32_t _use_cnt;
bool _peaks_built;
mutable Glib::Mutex _lock;
jack_nframes_t _length;
bool next_peak_clear_should_notify;
string peakpath;
time_t _timestamp; time_t _timestamp;
string _captured_for;
mutable uint32_t _read_data_count; // modified in read()
mutable uint32_t _write_data_count; // modified in write()
int initialize_peakfile (bool newfile, string path);
void build_peaks_from_scratch ();
int do_build_peak (jack_nframes_t, jack_nframes_t);
virtual jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const = 0;
virtual string peak_path(string audio_path) = 0;
static pthread_t peak_thread;
static bool have_peak_thread;
static void* peak_thread_work(void*);
static int peak_request_pipe[2];
struct PeakRequest {
enum Type {
Build,
Quit
};
};
static vector<Source*> pending_peak_sources;
static Glib::StaticMutex pending_peak_sources_lock;
static void queue_for_peaks (Source&);
static void clear_queue_for_peaks ();
struct PeakBuildRecord {
jack_nframes_t frame;
jack_nframes_t cnt;
PeakBuildRecord (jack_nframes_t f, jack_nframes_t c)
: frame (f), cnt (c) {}
PeakBuildRecord (const PeakBuildRecord& other) {
frame = other.frame;
cnt = other.cnt;
}
};
list<Source::PeakBuildRecord *> pending_peak_builds;
private: private:
ARDOUR::id_t _id; ARDOUR::id_t _id;
bool file_changed (string path);
}; };
} }

View file

@ -255,10 +255,18 @@ namespace ARDOUR {
BWF, BWF,
WAVE, WAVE,
WAVE64, WAVE64,
CAF,
AIFF,
iXML, iXML,
RF64 RF64
}; };
struct PeakData {
typedef Sample PeakDatum;
PeakDatum min;
PeakDatum max;
};
}; };
std::istream& operator>>(std::istream& o, ARDOUR::SampleFormat& sf); std::istream& operator>>(std::istream& o, ARDOUR::SampleFormat& sf);

View file

@ -23,10 +23,11 @@
#include <sigc++/bind.h> #include <sigc++/bind.h>
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/redirect.h> #include <ardour/redirect.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>
#include <ardour/audiosource.h>
#include <ardour/route_group_specialized.h> #include <ardour/route_group_specialized.h>
#include <ardour/insert.h> #include <ardour/insert.h>
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
@ -43,19 +44,19 @@ AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode
diskstream (0), diskstream (0),
_midi_rec_enable_control (*this, _session.midi_port()) _midi_rec_enable_control (*this, _session.midi_port())
{ {
DiskStream::Flag dflags = DiskStream::Flag (0); AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0);
if (_flags & Hidden) { if (_flags & Hidden) {
dflags = DiskStream::Flag (dflags | DiskStream::Hidden); dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Hidden);
} else { } else {
dflags = DiskStream::Flag (dflags | DiskStream::Recordable); dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Recordable);
} }
if (mode == Destructive) { if (mode == Destructive) {
dflags = DiskStream::Flag (dflags | DiskStream::Destructive); dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Destructive);
} }
DiskStream* ds = new DiskStream (_session, name, dflags); AudioDiskstream* ds = new AudioDiskstream (_session, name, dflags);
_declickable = true; _declickable = true;
_freeze_record.state = NoFreeze; _freeze_record.state = NoFreeze;
@ -64,6 +65,8 @@ AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode
set_diskstream (*ds, this); set_diskstream (*ds, this);
// session.SMPTEOffsetChanged.connect (mem_fun (*this, &AudioTrack::handle_smpte_offset_change));
// we do this even though Route already did it in it's init // we do this even though Route already did it in it's init
reset_midi_control (_session.midi_port(), _session.get_midi_control()); reset_midi_control (_session.midi_port(), _session.get_midi_control());
@ -90,6 +93,14 @@ AudioTrack::~AudioTrack ()
} }
} }
#if 0
void
AudioTrack::handle_smpte_offset_change ()
{
diskstream
}
#endif
int int
AudioTrack::deprecated_use_diskstream_connections () AudioTrack::deprecated_use_diskstream_connections ()
{ {
@ -143,7 +154,7 @@ AudioTrack::deprecated_use_diskstream_connections ()
} }
int int
AudioTrack::set_diskstream (DiskStream& ds, void *src) AudioTrack::set_diskstream (AudioDiskstream& ds, void *src)
{ {
if (diskstream) { if (diskstream) {
diskstream->unref(); diskstream->unref();
@ -166,7 +177,7 @@ AudioTrack::set_diskstream (DiskStream& ds, void *src)
diskstream->monitor_input (false); diskstream->monitor_input (false);
ic_connection.disconnect(); ic_connection.disconnect();
ic_connection = input_changed.connect (mem_fun (*diskstream, &DiskStream::handle_input_change)); ic_connection = input_changed.connect (mem_fun (*diskstream, &AudioDiskstream::handle_input_change));
diskstream_changed (src); /* EMIT SIGNAL */ diskstream_changed (src); /* EMIT SIGNAL */
@ -176,7 +187,7 @@ AudioTrack::set_diskstream (DiskStream& ds, void *src)
int int
AudioTrack::use_diskstream (string name) AudioTrack::use_diskstream (string name)
{ {
DiskStream *dstream; AudioDiskstream *dstream;
if ((dstream = _session.diskstream_by_name (name)) == 0) { if ((dstream = _session.diskstream_by_name (name)) == 0) {
error << string_compose(_("AudioTrack: diskstream \"%1\" not known by session"), name) << endmsg; error << string_compose(_("AudioTrack: diskstream \"%1\" not known by session"), name) << endmsg;
@ -189,7 +200,7 @@ AudioTrack::use_diskstream (string name)
int int
AudioTrack::use_diskstream (id_t id) AudioTrack::use_diskstream (id_t id)
{ {
DiskStream *dstream; AudioDiskstream *dstream;
if ((dstream = _session.diskstream_by_id (id)) == 0) { if ((dstream = _session.diskstream_by_id (id)) == 0) {
error << string_compose(_("AudioTrack: diskstream \"%1\" not known by session"), id) << endmsg; error << string_compose(_("AudioTrack: diskstream \"%1\" not known by session"), id) << endmsg;
@ -899,23 +910,23 @@ AudioTrack::update_total_latency ()
void void
AudioTrack::bounce (InterThreadInfo& itt) AudioTrack::bounce (InterThreadInfo& itt)
{ {
vector<Source*> srcs; vector<AudioSource*> srcs;
_session.write_one_track (*this, 0, _session.current_end_frame(), false, srcs, itt); _session.write_one_audio_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
} }
void void
AudioTrack::bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadInfo& itt) AudioTrack::bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadInfo& itt)
{ {
vector<Source*> srcs; vector<AudioSource*> srcs;
_session.write_one_track (*this, start, end, false, srcs, itt); _session.write_one_audio_track (*this, start, end, false, srcs, itt);
} }
void void
AudioTrack::freeze (InterThreadInfo& itt) AudioTrack::freeze (InterThreadInfo& itt)
{ {
Insert* insert; Insert* insert;
vector<Source*> srcs; vector<AudioSource*> srcs;
string new_playlist_name; string new_playlist_name;
Playlist* new_playlist; Playlist* new_playlist;
string dir; string dir;
@ -950,7 +961,7 @@ AudioTrack::freeze (InterThreadInfo& itt)
return; return;
} }
if (_session.write_one_track (*this, 0, _session.current_end_frame(), true, srcs, itt)) { if (_session.write_one_audio_track (*this, 0, _session.current_end_frame(), true, srcs, itt)) {
return; return;
} }

View file

@ -229,9 +229,10 @@ AudioEngine::_freewheel_callback (int onoff, void *arg)
int int
AudioEngine::process_callback (jack_nframes_t nframes) AudioEngine::process_callback (jack_nframes_t nframes)
{ {
// CycleTimer ct ("AudioEngine::process");
Glib::Mutex::Lock tm (_process_lock, Glib::TRY_LOCK); Glib::Mutex::Lock tm (_process_lock, Glib::TRY_LOCK);
jack_nframes_t next_processed_frames; jack_nframes_t next_processed_frames;
/* handle wrap around of total frames counter */ /* handle wrap around of total frames counter */
if (max_frames - _processed_frames < nframes) { if (max_frames - _processed_frames < nframes) {

View file

@ -22,7 +22,7 @@
#include <cerrno> #include <cerrno>
#include <pbd/basename.h> #include <pbd/basename.h>
#include <ardour/filesource.h> #include <ardour/sndfilesource.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>
#include <ardour/audiofilter.h> #include <ardour/audiofilter.h>
@ -47,7 +47,10 @@ AudioFilter::make_new_sources (AudioRegion& region, AudioRegion::SourceList& nsr
} }
try { try {
nsrcs.push_back (new FileSource (path, session.frame_rate(), false, Config->get_native_file_data_format())); nsrcs.push_back (new SndFileSource (path,
Config->get_native_file_data_format(),
Config->get_native_file_header_format(),
session.frame_rate()));
} }
catch (failed_constructor& err) { catch (failed_constructor& err) {
@ -73,7 +76,10 @@ AudioFilter::finish (AudioRegion& region, AudioRegion::SourceList& nsrcs)
now = localtime (&xnow); now = localtime (&xnow);
for (AudioRegion::SourceList::iterator si = nsrcs.begin(); si != nsrcs.end(); ++si) { for (AudioRegion::SourceList::iterator si = nsrcs.begin(); si != nsrcs.end(); ++si) {
dynamic_cast<FileSource*>((*si))->update_header (region.position(), *now, xnow); AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*si);
if (afs) {
afs->update_header (region.position(), *now, xnow);
}
} }
/* create a new region */ /* create a new region */

View file

@ -38,6 +38,7 @@
#include <ardour/dB.h> #include <ardour/dB.h>
#include <ardour/playlist.h> #include <ardour/playlist.h>
#include <ardour/audiofilter.h> #include <ardour/audiofilter.h>
#include <ardour/audiosource.h>
#include "i18n.h" #include "i18n.h"
#include <locale.h> #include <locale.h>
@ -63,7 +64,7 @@ AudioRegionState::AudioRegionState (string why)
{ {
} }
AudioRegion::AudioRegion (Source& src, jack_nframes_t start, jack_nframes_t length, bool announce) AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t length, bool announce)
: Region (start, length, PBD::basename_nosuffix(src.name()), 0, Region::Flag(Region::DefaultFlags|Region::External)), : Region (start, length, PBD::basename_nosuffix(src.name()), 0, Region::Flag(Region::DefaultFlags|Region::External)),
_fade_in (0.0, 2.0, 1.0, false), _fade_in (0.0, 2.0, 1.0, false),
_fade_out (0.0, 2.0, 1.0, false), _fade_out (0.0, 2.0, 1.0, false),
@ -89,7 +90,7 @@ AudioRegion::AudioRegion (Source& src, jack_nframes_t start, jack_nframes_t leng
} }
} }
AudioRegion::AudioRegion (Source& src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce) AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce)
: Region (start, length, name, layer, flags), : Region (start, length, name, layer, flags),
_fade_in (0.0, 2.0, 1.0, false), _fade_in (0.0, 2.0, 1.0, false),
_fade_out (0.0, 2.0, 1.0, false), _fade_out (0.0, 2.0, 1.0, false),
@ -150,7 +151,7 @@ AudioRegion::AudioRegion (const AudioRegion& other, jack_nframes_t offset, jack_
{ {
/* create a new AudioRegion, that is part of an existing one */ /* create a new AudioRegion, that is part of an existing one */
set<Source*> unique_srcs; set<AudioSource*> unique_srcs;
for (SourceList::const_iterator i= other.sources.begin(); i != other.sources.end(); ++i) { for (SourceList::const_iterator i= other.sources.begin(); i != other.sources.end(); ++i) {
sources.push_back (*i); sources.push_back (*i);
@ -209,7 +210,7 @@ AudioRegion::AudioRegion (const AudioRegion &other)
{ {
/* Pure copy constructor */ /* Pure copy constructor */
set<Source*> unique_srcs; set<AudioSource*> unique_srcs;
for (SourceList::const_iterator i = other.sources.begin(); i != other.sources.end(); ++i) { for (SourceList::const_iterator i = other.sources.begin(); i != other.sources.end(); ++i) {
sources.push_back (*i); sources.push_back (*i);
@ -237,7 +238,7 @@ AudioRegion::AudioRegion (const AudioRegion &other)
/* NOTE: no CheckNewRegion signal emitted here. This is the copy constructor */ /* NOTE: no CheckNewRegion signal emitted here. This is the copy constructor */
} }
AudioRegion::AudioRegion (Source& src, const XMLNode& node) AudioRegion::AudioRegion (AudioSource& src, const XMLNode& node)
: Region (node), : Region (node),
_fade_in (0.0, 2.0, 1.0, false), _fade_in (0.0, 2.0, 1.0, false),
_fade_out (0.0, 2.0, 1.0, false), _fade_out (0.0, 2.0, 1.0, false),
@ -268,7 +269,7 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
{ {
/* basic AudioRegion constructor */ /* basic AudioRegion constructor */
set<Source*> unique_srcs; set<AudioSource*> unique_srcs;
for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) { for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) {
sources.push_back (*i); sources.push_back (*i);
@ -1094,7 +1095,7 @@ void
AudioRegion::lock_sources () AudioRegion::lock_sources ()
{ {
SourceList::iterator i; SourceList::iterator i;
set<Source*> unique_srcs; set<AudioSource*> unique_srcs;
for (i = sources.begin(); i != sources.end(); ++i) { for (i = sources.begin(); i != sources.end(); ++i) {
unique_srcs.insert (*i); unique_srcs.insert (*i);
@ -1112,7 +1113,7 @@ void
AudioRegion::unlock_sources () AudioRegion::unlock_sources ()
{ {
SourceList::iterator i; SourceList::iterator i;
set<Source*> unique_srcs; set<AudioSource*> unique_srcs;
for (i = sources.begin(); i != sources.end(); ++i) { for (i = sources.begin(); i != sources.end(); ++i) {
unique_srcs.insert (*i); unique_srcs.insert (*i);

View file

@ -20,7 +20,7 @@
#include <glibmm/thread.h> #include <glibmm/thread.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>
#include <ardour/route.h> #include <ardour/route.h>
#include <ardour/session.h> #include <ardour/session.h>

View file

@ -26,7 +26,7 @@
#include <ardour/ardour.h> #include <ardour/ardour.h>
#include <ardour/configuration.h> #include <ardour/configuration.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/destructive_filesource.h> #include <ardour/destructive_filesource.h>
#include <ardour/control_protocol_manager.h> #include <ardour/control_protocol_manager.h>
@ -231,7 +231,7 @@ Configuration::set_state (const XMLNode& root)
} }
} }
DiskStream::set_disk_io_chunk_frames (minimum_disk_io_bytes.get() / sizeof (Sample)); AudioDiskstream::set_disk_io_chunk_frames (minimum_disk_io_bytes.get() / sizeof (Sample));
return 0; return 0;
} }

View file

@ -66,13 +66,9 @@ gain_t* DestructiveFileSource::out_coefficient = 0;
gain_t* DestructiveFileSource::in_coefficient = 0; gain_t* DestructiveFileSource::in_coefficient = 0;
jack_nframes_t DestructiveFileSource::xfade_frames = 64; jack_nframes_t DestructiveFileSource::xfade_frames = 64;
DestructiveFileSource::DestructiveFileSource (string path, jack_nframes_t rate, bool repair_first, SampleFormat samp_format) DestructiveFileSource::DestructiveFileSource (string path, SampleFormat samp_format, HeaderFormat hdr_format, jack_nframes_t rate, Flag flags)
: FileSource (path, rate, repair_first, samp_format) : SndFileSource (path, samp_format, hdr_format, rate, flags)
{ {
if (out_coefficient == 0) {
setup_standard_crossfades (rate);
}
xfade_buf = new Sample[xfade_frames]; xfade_buf = new Sample[xfade_frames];
_capture_start = false; _capture_start = false;
@ -80,13 +76,9 @@ DestructiveFileSource::DestructiveFileSource (string path, jack_nframes_t rate,
file_pos = 0; file_pos = 0;
} }
DestructiveFileSource::DestructiveFileSource (const XMLNode& node, jack_nframes_t rate) DestructiveFileSource::DestructiveFileSource (const XMLNode& node)
: FileSource (node, rate) : SndFileSource (node)
{ {
if (out_coefficient == 0) {
setup_standard_crossfades (rate);
}
xfade_buf = new Sample[xfade_frames]; xfade_buf = new Sample[xfade_frames];
_capture_start = false; _capture_start = false;
@ -102,6 +94,10 @@ DestructiveFileSource::~DestructiveFileSource()
void void
DestructiveFileSource::setup_standard_crossfades (jack_nframes_t rate) DestructiveFileSource::setup_standard_crossfades (jack_nframes_t rate)
{ {
/* This static method is assumed to have been called by the Session
before any DFS's are created.
*/
xfade_frames = (jack_nframes_t) floor ((Config->get_destructive_xfade_msecs () / 1000.0) * rate); xfade_frames = (jack_nframes_t) floor ((Config->get_destructive_xfade_msecs () / 1000.0) * rate);
if (out_coefficient) { if (out_coefficient) {
@ -124,12 +120,6 @@ DestructiveFileSource::setup_standard_crossfades (jack_nframes_t rate)
} }
} }
int
DestructiveFileSource::seek (jack_nframes_t frame)
{
return 0;
}
void void
DestructiveFileSource::mark_capture_start (jack_nframes_t pos) DestructiveFileSource::mark_capture_start (jack_nframes_t pos)
{ {
@ -188,7 +178,7 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in,
} }
if (file_cnt) { if (file_cnt) {
if ((retval = file_read (xfade_buf, fade_position, file_cnt, workbuf)) != (ssize_t) file_cnt) { if ((retval = write_float (xfade_buf, fade_position, file_cnt)) != (ssize_t) file_cnt) {
if (retval >= 0 && errno == EAGAIN) { if (retval >= 0 && errno == EAGAIN) {
/* XXX - can we really trust that errno is meaningful here? yes POSIX, i'm talking to you. /* XXX - can we really trust that errno is meaningful here? yes POSIX, i'm talking to you.
* short or no data there */ * short or no data there */
@ -206,7 +196,7 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in,
} }
if (nofade && !fade_in) { if (nofade && !fade_in) {
if (file_write (data, file_pos, nofade, workbuf) != (ssize_t) nofade) { if (write_float (data, file_pos, nofade) != nofade) {
error << string_compose(_("DestructiveFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg; error << string_compose(_("DestructiveFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
return 0; return 0;
} }
@ -248,14 +238,14 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in,
} }
if (xfade) { if (xfade) {
if (file_write (xfade_buf, fade_position, xfade, workbuf) != (ssize_t) xfade) { if (write_float (xfade_buf, fade_position, xfade) != xfade) {
error << string_compose(_("DestructiveFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg; error << string_compose(_("DestructiveFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
return 0; return 0;
} }
} }
if (fade_in && nofade) { if (fade_in && nofade) {
if (file_write (data + xfade, file_pos + xfade, nofade, workbuf) != (ssize_t) nofade) { if (write_float (data + xfade, file_pos + xfade, nofade) != nofade) {
error << string_compose(_("DestructiveFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg; error << string_compose(_("DestructiveFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
return 0; return 0;
} }
@ -265,96 +255,100 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in,
} }
jack_nframes_t jack_nframes_t
DestructiveFileSource::write (Sample* data, jack_nframes_t cnt, char * workbuf) DestructiveFileSource::write_unlocked (Sample* data, jack_nframes_t start, jack_nframes_t cnt, char * workbuf)
{ {
{ jack_nframes_t old_file_pos;
Glib::Mutex::Lock lm (_lock);
if (!writable()) {
return 0;
}
if (_capture_start && _capture_end) {
_capture_start = false;
_capture_end = false;
jack_nframes_t old_file_pos; /* move to the correct location place */
file_pos = capture_start_frame;
if (_capture_start && _capture_end) {
_capture_start = false; // split cnt in half
_capture_end = false; jack_nframes_t subcnt = cnt / 2;
jack_nframes_t ofilepos = file_pos;
/* move to the correct location place */
file_pos = capture_start_frame; // fade in
if (crossfade (data, subcnt, 1, workbuf) != subcnt) {
// split cnt in half return 0;
jack_nframes_t subcnt = cnt / 2;
jack_nframes_t ofilepos = file_pos;
// fade in
if (crossfade (data, subcnt, 1, workbuf) != subcnt) {
return 0;
}
file_pos += subcnt;
Sample * tmpdata = data + subcnt;
// fade out
subcnt = cnt - subcnt;
if (crossfade (tmpdata, subcnt, 0, workbuf) != subcnt) {
return 0;
}
file_pos = ofilepos; // adjusted below
} }
else if (_capture_start) {
_capture_start = false; file_pos += subcnt;
_capture_end = false; Sample * tmpdata = data + subcnt;
// fade out
subcnt = cnt - subcnt;
if (crossfade (tmpdata, subcnt, 0, workbuf) != subcnt) {
return 0;
}
file_pos = ofilepos; // adjusted below
}
else if (_capture_start) {
/* move to the correct location place */ _capture_start = false;
file_pos = capture_start_frame; _capture_end = false;
/* move to the correct location place */
file_pos = capture_start_frame;
if (crossfade (data, cnt, 1, workbuf) != cnt) {
return 0;
}
} else if (_capture_end) {
_capture_start = false;
_capture_end = false;
if (crossfade (data, cnt, 0, workbuf) != cnt) {
return 0;
}
} else {
if (write_float (data, file_pos, cnt) != cnt) {
return 0;
}
}
old_file_pos = file_pos;
if (file_pos + cnt > _length) {
_length = file_pos + cnt;
}
file_pos += cnt;
if (_build_peakfiles) {
PeakBuildRecord *pbr = 0;
if (pending_peak_builds.size()) {
pbr = pending_peak_builds.back();
}
if (pbr && pbr->frame + pbr->cnt == old_file_pos) {
if (crossfade (data, cnt, 1, workbuf) != cnt) { /* the last PBR extended to the start of the current write,
return 0; so just extend it again.
} */
} else if (_capture_end) { pbr->cnt += cnt;
_capture_start = false;
_capture_end = false;
if (crossfade (data, cnt, 0, workbuf) != cnt) {
return 0;
}
} else { } else {
if (file_write(data, file_pos, cnt, workbuf) != (ssize_t) cnt) { pending_peak_builds.push_back (new PeakBuildRecord (old_file_pos, cnt));
return 0;
}
} }
old_file_pos = file_pos;
if (file_pos + cnt > _length) {
_length = file_pos + cnt;
}
file_pos += cnt;
if (_build_peakfiles) { _peaks_built = false;
PeakBuildRecord *pbr = 0;
if (pending_peak_builds.size()) {
pbr = pending_peak_builds.back();
}
if (pbr && pbr->frame + pbr->cnt == old_file_pos) {
/* the last PBR extended to the start of the current write,
so just extend it again.
*/
pbr->cnt += cnt;
} else {
pending_peak_builds.push_back (new PeakBuildRecord (old_file_pos, cnt));
}
_peaks_built = false;
}
} }
if (_build_peakfiles) { if (_build_peakfiles) {
queue_for_peaks (*this); queue_for_peaks (*this);
} }
return cnt; return cnt;
} }
@ -367,7 +361,14 @@ DestructiveFileSource::last_capture_start_frame () const
XMLNode& XMLNode&
DestructiveFileSource::get_state () DestructiveFileSource::get_state ()
{ {
XMLNode& node = FileSource::get_state (); XMLNode& node = AudioFileSource::get_state ();
node.add_property (X_("destructive"), "true"); node.add_property (X_("destructive"), "true");
return node; return node;
} }
void
DestructiveFileSource::set_timeline_position (jack_nframes_t pos)
{
/* destructive tracks always start at where our reference frame zero is */
timeline_position = 0;
}

View file

@ -62,8 +62,7 @@
#include <ardour/ardour.h> #include <ardour/ardour.h>
#include <ardour/version.h> #include <ardour/version.h>
#include <ardour/source.h> #include <ardour/audiofilesource.h>
#include <ardour/filesource.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/cycle_timer.h> #include <ardour/cycle_timer.h>
#include <ardour/pcm_utils.h> #include <ardour/pcm_utils.h>

View file

@ -43,7 +43,7 @@
#include <ardour/audio_library.h> #include <ardour/audio_library.h>
#include <ardour/configuration.h> #include <ardour/configuration.h>
#include <ardour/plugin_manager.h> #include <ardour/plugin_manager.h>
#include <ardour/source.h> #include <ardour/audiosource.h>
#include <ardour/utils.h> #include <ardour/utils.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/control_protocol_manager.h> #include <ardour/control_protocol_manager.h>

View file

@ -36,8 +36,8 @@
#include <ardour/ardour.h> #include <ardour/ardour.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/filesource.h> #include <ardour/sndfilesource.h>
#include <ardour/sndfile_helpers.h> #include <ardour/sndfile_helpers.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>
@ -51,8 +51,8 @@ int
Session::import_audiofile (import_status& status) Session::import_audiofile (import_status& status)
{ {
SNDFILE *in; SNDFILE *in;
FileSource **newfiles = 0; AudioFileSource **newfiles = 0;
ARDOUR::AudioRegion::SourceList sources; AudioRegion::SourceList sources;
SF_INFO info; SF_INFO info;
float *data = 0; float *data = 0;
Sample **channel_data = 0; Sample **channel_data = 0;
@ -94,7 +94,7 @@ Session::import_audiofile (import_status& status)
} }
} }
newfiles = new FileSource *[info.channels]; newfiles = new AudioFileSource *[info.channels];
for (n = 0; n < info.channels; ++n) { for (n = 0; n < info.channels; ++n) {
newfiles[n] = 0; newfiles[n] = 0;
} }
@ -137,7 +137,10 @@ Session::import_audiofile (import_status& status)
try { try {
newfiles[n] = new FileSource (buf, frame_rate(), false, Config->get_native_file_data_format()); newfiles[n] = new SndFileSource (buf,
Config->get_native_file_data_format(),
Config->get_native_file_header_format(),
frame_rate ());
} }
catch (failed_constructor& err) { catch (failed_constructor& err) {

View file

@ -309,7 +309,6 @@ OSC::osc_receiver()
if ((ret = poll (pfd, nfds, timeout)) < 0) { if ((ret = poll (pfd, nfds, timeout)) < 0) {
if (errno == EINTR) { if (errno == EINTR) {
/* gdb at work, perhaps */ /* gdb at work, perhaps */
cerr << "EINTR hit " << endl;
goto again; goto again;
} }

View file

@ -24,7 +24,7 @@
#include <ardour/types.h> #include <ardour/types.h>
#include <ardour/reverse.h> #include <ardour/reverse.h>
#include <ardour/filesource.h> #include <ardour/audiofilesource.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>

View file

@ -29,7 +29,7 @@
#include <ardour/route_group.h> #include <ardour/route_group.h>
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/configuration.h> #include <ardour/configuration.h>
using namespace ARDOUR; using namespace ARDOUR;

View file

@ -32,7 +32,8 @@
#include <sigc++/bind.h> #include <sigc++/bind.h>
#include <sigc++/retype.h> #include <sigc++/retype.h>
#include <glibmm.h> #include <glibmm/thread.h>
#include <glibmm/miscutils.h>
#include <pbd/error.h> #include <pbd/error.h>
#include <glibmm/thread.h> #include <glibmm/thread.h>
@ -43,14 +44,12 @@
#include <ardour/audioengine.h> #include <ardour/audioengine.h>
#include <ardour/configuration.h> #include <ardour/configuration.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/utils.h> #include <ardour/utils.h>
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>
#include <ardour/source.h> #include <ardour/audiofilesource.h>
#include <ardour/filesource.h>
#include <ardour/destructive_filesource.h> #include <ardour/destructive_filesource.h>
#include <ardour/sndfilesource.h>
#include <ardour/auditioner.h> #include <ardour/auditioner.h>
#include <ardour/recent_sessions.h> #include <ardour/recent_sessions.h>
#include <ardour/redirect.h> #include <ardour/redirect.h>
@ -90,6 +89,7 @@ Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0;
Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0; Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
sigc::signal<int> Session::AskAboutPendingState; sigc::signal<int> Session::AskAboutPendingState;
sigc::signal<void> Session::SMPTEOffsetChanged;
int int
Session::find_session (string str, string& path, string& snapshot, bool& isnew) Session::find_session (string str, string& path, string& snapshot, bool& isnew)
@ -455,10 +455,10 @@ Session::~Session ()
} }
#ifdef TRACK_DESTRUCTION #ifdef TRACK_DESTRUCTION
cerr << "delete diskstreams\n"; cerr << "delete audio_diskstreams\n";
#endif /* TRACK_DESTRUCTION */ #endif /* TRACK_DESTRUCTION */
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ) {
DiskStreamList::iterator tmp; AudioDiskstreamList::iterator tmp;
tmp = i; tmp = i;
++tmp; ++tmp;
@ -469,10 +469,10 @@ Session::~Session ()
} }
#ifdef TRACK_DESTRUCTION #ifdef TRACK_DESTRUCTION
cerr << "delete sources\n"; cerr << "delete audio sources\n";
#endif /* TRACK_DESTRUCTION */ #endif /* TRACK_DESTRUCTION */
for (SourceList::iterator i = sources.begin(); i != sources.end(); ) { for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
SourceList::iterator tmp; AudioSourceList::iterator tmp;
tmp = i; tmp = i;
++tmp; ++tmp;
@ -881,7 +881,7 @@ Session::playlist_length_changed (Playlist* pl)
} }
void void
Session::diskstream_playlist_changed (DiskStream* dstream) Session::diskstream_playlist_changed (AudioDiskstream* dstream)
{ {
Playlist *playlist; Playlist *playlist;
@ -961,7 +961,7 @@ Session::set_auto_input (bool yn)
The rarity and short potential lock duration makes this "OK" The rarity and short potential lock duration makes this "OK"
*/ */
Glib::RWLock::ReaderLock dsm (diskstream_lock); Glib::RWLock::ReaderLock dsm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if ((*i)->record_enabled ()) { if ((*i)->record_enabled ()) {
//cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl; //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (!auto_input); (*i)->monitor_input (!auto_input);
@ -979,7 +979,7 @@ Session::reset_input_monitor_state ()
{ {
if (transport_rolling()) { if (transport_rolling()) {
Glib::RWLock::ReaderLock dsm (diskstream_lock); Glib::RWLock::ReaderLock dsm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if ((*i)->record_enabled ()) { if ((*i)->record_enabled ()) {
//cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl; //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input); (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
@ -987,7 +987,7 @@ Session::reset_input_monitor_state ()
} }
} else { } else {
Glib::RWLock::ReaderLock dsm (diskstream_lock); Glib::RWLock::ReaderLock dsm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if ((*i)->record_enabled ()) { if ((*i)->record_enabled ()) {
//cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl; //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (Config->get_use_hardware_monitoring()); (*i)->monitor_input (Config->get_use_hardware_monitoring());
@ -1068,7 +1068,7 @@ Session::auto_loop_changed (Location* location)
} }
else if (seamless_loop && !loop_changing) { else if (seamless_loop && !loop_changing) {
// schedule a locate-roll to refill the diskstreams at the // schedule a locate-roll to refill the audio_diskstreams at the
// previous loop end // previous loop end
loop_changing = true; loop_changing = true;
@ -1265,7 +1265,7 @@ Session::enable_record ()
*/ */
Glib::RWLock::ReaderLock dsm (diskstream_lock); Glib::RWLock::ReaderLock dsm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if ((*i)->record_enabled ()) { if ((*i)->record_enabled ()) {
(*i)->monitor_input (true); (*i)->monitor_input (true);
} }
@ -1300,7 +1300,7 @@ Session::disable_record (bool rt_context, bool force)
*/ */
Glib::RWLock::ReaderLock dsm (diskstream_lock); Glib::RWLock::ReaderLock dsm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if ((*i)->record_enabled ()) { if ((*i)->record_enabled ()) {
(*i)->monitor_input (false); (*i)->monitor_input (false);
} }
@ -1327,7 +1327,7 @@ Session::step_back_from_record ()
*/ */
Glib::RWLock::ReaderLock dsm (diskstream_lock); Glib::RWLock::ReaderLock dsm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if (auto_input && (*i)->record_enabled ()) { if (auto_input && (*i)->record_enabled ()) {
//cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl; //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (false); (*i)->monitor_input (false);
@ -1432,6 +1432,9 @@ Session::set_frame_rate (jack_nframes_t frames_per_second)
Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25)); Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
// XXX we need some equivalent to this, somehow
// DestructiveFileSource::setup_standard_crossfades (frames_per_second);
set_dirty(); set_dirty();
/* XXX need to reset/reinstantiate all LADSPA plugins */ /* XXX need to reset/reinstantiate all LADSPA plugins */
@ -1493,7 +1496,7 @@ Session::set_block_size (jack_nframes_t nframes)
(*i)->set_block_size (nframes); (*i)->set_block_size (nframes);
} }
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
(*i)->set_block_size (nframes); (*i)->set_block_size (nframes);
} }
@ -1900,14 +1903,14 @@ Session::add_route (Route* route)
} }
void void
Session::add_diskstream (DiskStream* dstream) Session::add_diskstream (AudioDiskstream* dstream)
{ {
/* need to do this in case we're rolling at the time, to prevent false underruns */ /* need to do this in case we're rolling at the time, to prevent false underruns */
dstream->do_refill(0, 0, 0); dstream->do_refill(0, 0, 0);
{ {
Glib::RWLock::WriterLock lm (diskstream_lock); Glib::RWLock::WriterLock lm (diskstream_lock);
diskstreams.push_back (dstream); audio_diskstreams.push_back (dstream);
} }
/* take a reference to the diskstream, preventing it from /* take a reference to the diskstream, preventing it from
@ -1927,7 +1930,7 @@ Session::add_diskstream (DiskStream* dstream)
set_dirty(); set_dirty();
save_state (_current_snapshot_name); save_state (_current_snapshot_name);
DiskStreamAdded (dstream); /* EMIT SIGNAL */ AudioDiskstreamAdded (dstream); /* EMIT SIGNAL */
} }
void void
@ -1961,18 +1964,24 @@ Session::remove_route (Route& route)
update_route_solo_state (); update_route_solo_state ();
} }
{ AudioTrack* at;
Glib::RWLock::WriterLock lm (diskstream_lock); AudioDiskstream* ds = 0;
if ((at = dynamic_cast<AudioTrack*>(&route)) != 0) {
ds = &at->disk_stream();
}
if (ds) {
AudioTrack* at; {
Glib::RWLock::WriterLock lm (diskstream_lock);
if ((at = dynamic_cast<AudioTrack*>(&route)) != 0) { audio_diskstreams.remove (ds);
diskstreams.remove (&at->disk_stream());
at->disk_stream().unref ();
} }
find_current_end (); ds->unref ();
} }
find_current_end ();
update_latency_compensation (false, false); update_latency_compensation (false, false);
set_dirty(); set_dirty();
@ -2255,7 +2264,7 @@ Session::get_maximum_extent () const
ensure atomicity. ensure atomicity.
*/ */
for (DiskStreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::const_iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
Playlist* pl = (*i)->playlist(); Playlist* pl = (*i)->playlist();
if ((me = pl->get_maximum_extent()) > max) { if ((me = pl->get_maximum_extent()) > max) {
max = me; max = me;
@ -2265,12 +2274,12 @@ Session::get_maximum_extent () const
return max; return max;
} }
DiskStream * AudioDiskstream *
Session::diskstream_by_name (string name) Session::diskstream_by_name (string name)
{ {
Glib::RWLock::ReaderLock lm (diskstream_lock); Glib::RWLock::ReaderLock lm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if ((*i)->name() == name) { if ((*i)->name() == name) {
return* i; return* i;
} }
@ -2279,12 +2288,12 @@ Session::diskstream_by_name (string name)
return 0; return 0;
} }
DiskStream * AudioDiskstream *
Session::diskstream_by_id (id_t id) Session::diskstream_by_id (id_t id)
{ {
Glib::RWLock::ReaderLock lm (diskstream_lock); Glib::RWLock::ReaderLock lm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if ((*i)->id() == id) { if ((*i)->id() == id) {
return *i; return *i;
} }
@ -2583,7 +2592,10 @@ Session::destroy_region (Region* region)
for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) { for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
if ((*i)->use_cnt() == 0) { if ((*i)->use_cnt() == 0) {
(*i)->mark_for_remove (); AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*i);
if (afs) {
(afs)->mark_for_remove ();
}
delete *i; delete *i;
} }
} }
@ -2607,7 +2619,7 @@ Session::remove_last_capture ()
Glib::RWLock::ReaderLock lm (diskstream_lock); Glib::RWLock::ReaderLock lm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
list<Region*>& l = (*i)->last_capture_regions(); list<Region*>& l = (*i)->last_capture_regions();
if (!l.empty()) { if (!l.empty()) {
@ -2630,15 +2642,15 @@ Session::remove_region_from_region_list (Region& r)
/* Source Management */ /* Source Management */
void void
Session::add_source (Source* source) Session::add_audio_source (AudioSource* source)
{ {
pair<SourceList::key_type, SourceList::mapped_type> entry; pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
{ {
Glib::Mutex::Lock lm (source_lock); Glib::Mutex::Lock lm (audio_source_lock);
entry.first = source->id(); entry.first = source->id();
entry.second = source; entry.second = source;
sources.insert (entry); audio_sources.insert (entry);
} }
source->GoingAway.connect (mem_fun (this, &Session::remove_source)); source->GoingAway.connect (mem_fun (this, &Session::remove_source));
@ -2650,13 +2662,13 @@ Session::add_source (Source* source)
void void
Session::remove_source (Source* source) Session::remove_source (Source* source)
{ {
SourceList::iterator i; AudioSourceList::iterator i;
{ {
Glib::Mutex::Lock lm (source_lock); Glib::Mutex::Lock lm (audio_source_lock);
if ((i = sources.find (source->id())) != sources.end()) { if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
sources.erase (i); audio_sources.erase (i);
} }
} }
@ -2675,15 +2687,21 @@ Session::remove_source (Source* source)
Source * Source *
Session::get_source (ARDOUR::id_t id) Session::get_source (ARDOUR::id_t id)
{ {
Glib::Mutex::Lock lm (source_lock); Glib::Mutex::Lock lm (audio_source_lock);
SourceList::iterator i; AudioSourceList::iterator i;
Source* source = 0; Source* source = 0;
if ((i = sources.find (id)) != sources.end()) { if ((i = audio_sources.find (id)) != audio_sources.end()) {
source = (*i).second; source = (*i).second;
} }
return source; if (source) {
return source;
}
/* XXX search MIDI or other searches here */
return 0;
} }
string string
@ -2890,17 +2908,23 @@ Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool
return spath; return spath;
} }
FileSource * AudioFileSource *
Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive) Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
{ {
string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive); string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
/* this might throw failed_constructor(), which is OK */ /* this might throw failed_constructor(), which is OK */
if (destructive) { if (destructive) {
return new DestructiveFileSource (spath, frame_rate(), false, Config->get_native_file_data_format()); return new DestructiveFileSource (spath,
Config->get_native_file_data_format(),
Config->get_native_file_header_format(),
frame_rate());
} else { } else {
return new FileSource (spath, frame_rate(), false, Config->get_native_file_data_format()); return new SndFileSource (spath,
Config->get_native_file_data_format(),
Config->get_native_file_header_format(),
frame_rate());
} }
} }
@ -3082,7 +3106,7 @@ Session::remove_empty_sounds ()
for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) { for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
if (FileSource::is_empty (*(*i))) { if (AudioFileSource::is_empty (*(*i))) {
unlink ((*i)->c_str()); unlink ((*i)->c_str());
@ -3140,12 +3164,12 @@ Session::set_all_mute (bool yn)
} }
uint32_t uint32_t
Session::n_diskstreams () const Session::n_audio_diskstreams () const
{ {
Glib::RWLock::ReaderLock lm (diskstream_lock); Glib::RWLock::ReaderLock lm (diskstream_lock);
uint32_t n = 0; uint32_t n = 0;
for (DiskStreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::const_iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if (!(*i)->hidden()) { if (!(*i)->hidden()) {
n++; n++;
} }
@ -3154,10 +3178,10 @@ Session::n_diskstreams () const
} }
void void
Session::foreach_diskstream (void (DiskStream::*func)(void)) Session::foreach_audio_diskstream (void (AudioDiskstream::*func)(void))
{ {
Glib::RWLock::ReaderLock lm (diskstream_lock); Glib::RWLock::ReaderLock lm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if (!(*i)->hidden()) { if (!(*i)->hidden()) {
((*i)->*func)(); ((*i)->*func)();
} }
@ -3184,7 +3208,7 @@ Session::graph_reordered ()
reflect any changes in latencies within the graph. reflect any changes in latencies within the graph.
*/ */
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
(*i)->set_capture_offset (); (*i)->set_capture_offset ();
} }
} }
@ -3467,7 +3491,7 @@ Session::reset_native_file_format ()
//RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__); //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
Glib::RWLock::ReaderLock lm2 (diskstream_lock); Glib::RWLock::ReaderLock lm2 (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
(*i)->reset_write_sources (false); (*i)->reset_write_sources (false);
} }
} }
@ -3487,7 +3511,7 @@ Session::route_name_unique (string n) const
} }
int int
Session::remove_file_source (FileSource& fs) Session::cleanup_audio_file_source (AudioFileSource& fs)
{ {
return fs.move_to_trash (dead_sound_dir_name); return fs.move_to_trash (dead_sound_dir_name);
} }
@ -3562,12 +3586,12 @@ Session::freeze (InterThreadInfo& itt)
} }
int int
Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len, bool overwrite, vector<Source*>& srcs, Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
InterThreadInfo& itt) bool overwrite, vector<AudioSource*>& srcs, InterThreadInfo& itt)
{ {
int ret = -1; int ret = -1;
Playlist* playlist; Playlist* playlist;
FileSource* fsource; AudioFileSource* fsource;
uint32_t x; uint32_t x;
char buf[PATH_MAX+1]; char buf[PATH_MAX+1];
string dir; string dir;
@ -3612,7 +3636,11 @@ Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_
} }
try { try {
fsource = new FileSource (buf, frame_rate(), false, Config->get_native_file_data_format()); fsource = new SndFileSource (buf,
Config->get_native_file_data_format(),
Config->get_native_file_header_format(),
frame_rate());
} }
catch (failed_constructor& err) { catch (failed_constructor& err) {
@ -3651,9 +3679,13 @@ Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_
} }
uint32_t n = 0; uint32_t n = 0;
for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) { for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
if ((*src)->write (buffers[n], this_chunk, workbuf) != this_chunk) { AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
goto out;
if (afs) {
if (afs->write (buffers[n], this_chunk, workbuf) != this_chunk) {
goto out;
}
} }
} }
@ -3671,14 +3703,20 @@ Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_
time (&now); time (&now);
xnow = localtime (&now); xnow = localtime (&now);
for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) { for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
dynamic_cast<FileSource*>((*src))->update_header (position, *xnow, now); AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
if (afs) {
afs->update_header (position, *xnow, now);
}
} }
/* build peakfile for new source */ /* build peakfile for new source */
for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) { for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
dynamic_cast<FileSource*>(*src)->build_peaks (); AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
if (afs) {
afs->build_peaks ();
}
} }
ret = 0; ret = 0;
@ -3686,8 +3724,11 @@ Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_
out: out:
if (ret) { if (ret) {
for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) { for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
dynamic_cast<FileSource*>(*src)->mark_for_remove (); AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
if (afs) {
afs->mark_for_remove ();
}
delete *src; delete *src;
} }
} }

View file

@ -34,7 +34,7 @@
#include <ardour/configuration.h> #include <ardour/configuration.h>
#include <ardour/audioengine.h> #include <ardour/audioengine.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/crossfade.h> #include <ardour/crossfade.h>
#include <ardour/timestamps.h> #include <ardour/timestamps.h>
@ -168,10 +168,10 @@ Session::butler_thread_work ()
struct timeval begin, end; struct timeval begin, end;
struct pollfd pfd[1]; struct pollfd pfd[1];
bool disk_work_outstanding = false; bool disk_work_outstanding = false;
DiskStreamList::iterator i; AudioDiskstreamList::iterator i;
butler_mixdown_buffer = new Sample[DiskStream::disk_io_frames()]; butler_mixdown_buffer = new Sample[AudioDiskstream::disk_io_frames()];
butler_gain_buffer = new gain_t[DiskStream::disk_io_frames()]; butler_gain_buffer = new gain_t[AudioDiskstream::disk_io_frames()];
// this buffer is used for temp conversion purposes in filesources // this buffer is used for temp conversion purposes in filesources
char * conv_buffer = conversion_buffer(ButlerContext); char * conv_buffer = conversion_buffer(ButlerContext);
@ -241,7 +241,7 @@ Session::butler_thread_work ()
} }
} }
for (i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
// cerr << "BEFORE " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl; // cerr << "BEFORE " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl;
} }
@ -257,7 +257,7 @@ Session::butler_thread_work ()
Glib::RWLock::ReaderLock dsm (diskstream_lock); Glib::RWLock::ReaderLock dsm (diskstream_lock);
for (i = diskstreams.begin(); !transport_work_requested() && butler_should_run && i != diskstreams.end(); ++i) { for (i = audio_diskstreams.begin(); !transport_work_requested() && butler_should_run && i != audio_diskstreams.end(); ++i) {
// cerr << "rah fondr " << (*i)->io()->name () << endl; // cerr << "rah fondr " << (*i)->io()->name () << endl;
@ -278,7 +278,7 @@ Session::butler_thread_work ()
} }
if (i != diskstreams.end()) { if (i != audio_diskstreams.end()) {
/* we didn't get to all the streams */ /* we didn't get to all the streams */
disk_work_outstanding = true; disk_work_outstanding = true;
} }
@ -300,7 +300,7 @@ Session::butler_thread_work ()
compute_io = true; compute_io = true;
gettimeofday (&begin, 0); gettimeofday (&begin, 0);
for (i = diskstreams.begin(); !transport_work_requested() && butler_should_run && i != diskstreams.end(); ++i) { for (i = audio_diskstreams.begin(); !transport_work_requested() && butler_should_run && i != audio_diskstreams.end(); ++i) {
// cerr << "write behind for " << (*i)->name () << endl; // cerr << "write behind for " << (*i)->name () << endl;
@ -330,7 +330,7 @@ Session::butler_thread_work ()
request_stop (); request_stop ();
} }
if (i != diskstreams.end()) { if (i != audio_diskstreams.end()) {
/* we didn't get to all the streams */ /* we didn't get to all the streams */
disk_work_outstanding = true; disk_work_outstanding = true;
} }
@ -357,7 +357,7 @@ Session::butler_thread_work ()
Glib::Mutex::Lock lm (butler_request_lock); Glib::Mutex::Lock lm (butler_request_lock);
if (butler_should_run && (disk_work_outstanding || transport_work_requested())) { if (butler_should_run && (disk_work_outstanding || transport_work_requested())) {
// for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { // for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
// cerr << "AFTER " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl; // cerr << "AFTER " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl;
// } // }
@ -375,7 +375,7 @@ Session::butler_thread_work ()
void void
Session::request_overwrite_buffer (DiskStream* stream) Session::request_overwrite_buffer (AudioDiskstream* stream)
{ {
Event *ev = new Event (Event::Overwrite, Event::Add, Event::Immediate, 0, 0, 0.0); Event *ev = new Event (Event::Overwrite, Event::Add, Event::Immediate, 0, 0, 0.0);
ev->set_ptr (stream); ev->set_ptr (stream);
@ -383,7 +383,7 @@ Session::request_overwrite_buffer (DiskStream* stream)
} }
void void
Session::overwrite_some_buffers (DiskStream* ds) Session::overwrite_some_buffers (AudioDiskstream* ds)
{ {
/* executed by the audio thread */ /* executed by the audio thread */
@ -398,7 +398,7 @@ Session::overwrite_some_buffers (DiskStream* ds)
} else { } else {
Glib::RWLock::ReaderLock dm (diskstream_lock); Glib::RWLock::ReaderLock dm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
(*i)->set_pending_overwrite (true); (*i)->set_pending_overwrite (true);
} }
} }

View file

@ -28,7 +28,7 @@
#include <ardour/ardour.h> #include <ardour/ardour.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include "i18n.h" #include "i18n.h"
@ -389,11 +389,11 @@ Session::process_event (Event* ev)
break; break;
case Event::Overwrite: case Event::Overwrite:
overwrite_some_buffers (static_cast<DiskStream*>(ev->ptr)); overwrite_some_buffers (static_cast<AudioDiskstream*>(ev->ptr));
break; break;
case Event::SetDiskstreamSpeed: case Event::SetDiskstreamSpeed:
set_diskstream_speed (static_cast<DiskStream*> (ev->ptr), ev->speed); set_diskstream_speed (static_cast<AudioDiskstream*> (ev->ptr), ev->speed);
break; break;
case Event::SetSlaveSource: case Event::SetSlaveSource:

View file

@ -47,7 +47,7 @@
#include <ardour/sndfile_helpers.h> #include <ardour/sndfile_helpers.h>
#include <ardour/port.h> #include <ardour/port.h>
#include <ardour/audioengine.h> #include <ardour/audioengine.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/panner.h> #include <ardour/panner.h>
#include "i18n.h" #include "i18n.h"
@ -495,7 +495,7 @@ Session::prepare_to_export (AudioExportSpecification& spec)
{ {
Glib::RWLock::ReaderLock lm (diskstream_lock); Glib::RWLock::ReaderLock lm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if ((*i)-> seek (spec.start_frame, true)) { if ((*i)-> seek (spec.start_frame, true)) {
error << string_compose (_("%1: cannot seek to %2 for export"), error << string_compose (_("%1: cannot seek to %2 for export"),
(*i)->name(), spec.start_frame) (*i)->name(), spec.start_frame)

View file

@ -38,7 +38,7 @@
#include <ardour/audioengine.h> #include <ardour/audioengine.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/control_protocol.h> #include <ardour/control_protocol.h>
#include "i18n.h" #include "i18n.h"

View file

@ -37,7 +37,7 @@
#include <ardour/audioengine.h> #include <ardour/audioengine.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/slave.h> #include <ardour/slave.h>
#include <ardour/cycles.h> #include <ardour/cycles.h>

View file

@ -30,7 +30,7 @@
#include <ardour/ardour.h> #include <ardour/ardour.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/timestamps.h> #include <ardour/timestamps.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/audioengine.h> #include <ardour/audioengine.h>
#include <ardour/slave.h> #include <ardour/slave.h>
#include <ardour/auditioner.h> #include <ardour/auditioner.h>
@ -64,7 +64,7 @@ Session::process (jack_nframes_t nframes)
void void
Session::prepare_diskstreams () Session::prepare_diskstreams ()
{ {
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
(*i)->prepare (); (*i)->prepare ();
} }
} }
@ -136,12 +136,12 @@ Session::process_routes (jack_nframes_t nframes, jack_nframes_t offset)
if ((ret = (*i)->roll (nframes, _transport_frame, _transport_frame + nframes, offset, declick, record_active, rec_monitors)) < 0) { if ((ret = (*i)->roll (nframes, _transport_frame, _transport_frame + nframes, offset, declick, record_active, rec_monitors)) < 0) {
/* we have to do this here. Route::roll() for an AudioTrack will have called DiskStream::process(), /* we have to do this here. Route::roll() for an AudioTrack will have called AudioDiskstream::process(),
and the DS will expect DiskStream::commit() to be called. but we're aborting from that and the DS will expect AudioDiskstream::commit() to be called. but we're aborting from that
call path, so make sure we release any outstanding locks here before we return failure. call path, so make sure we release any outstanding locks here before we return failure.
*/ */
for (DiskStreamList::iterator ids = diskstreams.begin(); ids != diskstreams.end(); ++ids) { for (AudioDiskstreamList::iterator ids = audio_diskstreams.begin(); ids != audio_diskstreams.end(); ++ids) {
(*ids)->recover (); (*ids)->recover ();
} }
@ -175,12 +175,12 @@ Session::silent_process_routes (jack_nframes_t nframes, jack_nframes_t offset)
if ((ret = (*i)->silent_roll (nframes, _transport_frame, _transport_frame + nframes, offset, record_active, rec_monitors)) < 0) { if ((ret = (*i)->silent_roll (nframes, _transport_frame, _transport_frame + nframes, offset, record_active, rec_monitors)) < 0) {
/* we have to do this here. Route::roll() for an AudioTrack will have called DiskStream::process(), /* we have to do this here. Route::roll() for an AudioTrack will have called AudioDiskstream::process(),
and the DS will expect DiskStream::commit() to be called. but we're aborting from that and the DS will expect AudioDiskstream::commit() to be called. but we're aborting from that
call path, so make sure we release any outstanding locks here before we return failure. call path, so make sure we release any outstanding locks here before we return failure.
*/ */
for (DiskStreamList::iterator ids = diskstreams.begin(); ids != diskstreams.end(); ++ids) { for (AudioDiskstreamList::iterator ids = audio_diskstreams.begin(); ids != audio_diskstreams.end(); ++ids) {
(*ids)->recover (); (*ids)->recover ();
} }
@ -199,7 +199,7 @@ Session::commit_diskstreams (jack_nframes_t nframes, bool &needs_butler)
float pworst = 1.0f; float pworst = 1.0f;
float cworst = 1.0f; float cworst = 1.0f;
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if ((*i)->hidden()) { if ((*i)->hidden()) {
continue; continue;
@ -566,7 +566,7 @@ Session::follow_slave (jack_nframes_t nframes, jack_nframes_t offset)
bool ok = true; bool ok = true;
jack_nframes_t frame_delta = slave_transport_frame - _transport_frame; jack_nframes_t frame_delta = slave_transport_frame - _transport_frame;
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if (!(*i)->can_internal_playback_seek (frame_delta)) { if (!(*i)->can_internal_playback_seek (frame_delta)) {
ok = false; ok = false;
break; break;
@ -574,7 +574,7 @@ Session::follow_slave (jack_nframes_t nframes, jack_nframes_t offset)
} }
if (ok) { if (ok) {
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
(*i)->internal_playback_seek (frame_delta); (*i)->internal_playback_seek (frame_delta);
} }
_transport_frame += frame_delta; _transport_frame += frame_delta;

View file

@ -58,13 +58,11 @@
#include <ardour/audioengine.h> #include <ardour/audioengine.h>
#include <ardour/configuration.h> #include <ardour/configuration.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/utils.h> #include <ardour/utils.h>
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
#include <ardour/source.h> #include <ardour/audiofilesource.h>
#include <ardour/filesource.h>
#include <ardour/destructive_filesource.h> #include <ardour/destructive_filesource.h>
#include <ardour/sndfilesource.h>
#include <ardour/sndfile_helpers.h> #include <ardour/sndfile_helpers.h>
#include <ardour/auditioner.h> #include <ardour/auditioner.h>
#include <ardour/export.h> #include <ardour/export.h>
@ -196,12 +194,13 @@ Session::first_stage_init (string fullpath, string snapshot_name)
destructive_index = 0; destructive_index = 0;
/* allocate conversion buffers */ /* allocate conversion buffers */
_conversion_buffers[ButlerContext] = new char[DiskStream::disk_io_frames() * 4]; _conversion_buffers[ButlerContext] = new char[AudioDiskstream::disk_io_frames() * 4];
_conversion_buffers[TransportContext] = new char[DiskStream::disk_io_frames() * 4]; _conversion_buffers[TransportContext] = new char[AudioDiskstream::disk_io_frames() * 4];
/* default short fade = 15ms */ /* default short fade = 15ms */
Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0)); Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0));
DestructiveFileSource::setup_standard_crossfades (frame_rate());
last_mmc_step.tv_sec = 0; last_mmc_step.tv_sec = 0;
last_mmc_step.tv_usec = 0; last_mmc_step.tv_usec = 0;
@ -267,10 +266,10 @@ Session::first_stage_init (string fullpath, string snapshot_name)
/* These are all static "per-class" signals */ /* These are all static "per-class" signals */
Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region)); Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
Source::SourceCreated.connect (mem_fun (*this, &Session::add_source)); AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source));
Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist)); Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect)); Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
DiskStream::DiskStreamCreated.connect (mem_fun (*this, &Session::add_diskstream)); AudioDiskstream::AudioDiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection)); NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers)); IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
@ -285,7 +284,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
int int
Session::second_stage_init (bool new_session) Session::second_stage_init (bool new_session)
{ {
ExternalSource::set_peak_dir (peak_dir()); AudioFileSource::set_peak_dir (peak_dir());
if (!new_session) { if (!new_session) {
if (load_state (_current_snapshot_name)) { if (load_state (_current_snapshot_name)) {
@ -425,7 +424,7 @@ Session::setup_raid_path (string path)
} }
fspath += tape_dir_name; fspath += tape_dir_name;
FileSource::set_search_path (fspath); AudioFileSource::set_search_path (fspath);
return; return;
} }
@ -481,9 +480,9 @@ Session::setup_raid_path (string path)
session_dirs.push_back (sp); session_dirs.push_back (sp);
} }
/* set the FileSource search path */ /* set the AudioFileSource search path */
FileSource::set_search_path (fspath); AudioFileSource::set_search_path (fspath);
/* reset the round-robin soundfile path thingie */ /* reset the round-robin soundfile path thingie */
@ -625,11 +624,11 @@ Session::load_diskstreams (const XMLNode& node)
for (citer = clist.begin(); citer != clist.end(); ++citer) { for (citer = clist.begin(); citer != clist.end(); ++citer) {
DiskStream* dstream; AudioDiskstream* dstream;
try { try {
dstream = new DiskStream (*this, **citer); dstream = new AudioDiskstream (*this, **citer);
/* added automatically by DiskStreamCreated handler */ /* added automatically by AudioDiskstreamCreated handler */
} }
catch (failed_constructor& err) { catch (failed_constructor& err) {
@ -1335,15 +1334,15 @@ Session::state(bool full_state)
child = node->add_child ("Sources"); child = node->add_child ("Sources");
if (full_state) { if (full_state) {
Glib::Mutex::Lock sl (source_lock); Glib::Mutex::Lock sl (audio_source_lock);
for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) { for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
/* Don't save information about FileSources that are empty */ /* Don't save information about AudioFileSources that are empty */
FileSource* fs; AudioFileSource* fs;
if ((fs = dynamic_cast<FileSource*> ((*siter).second)) != 0) { if ((fs = dynamic_cast<AudioFileSource*> ((*siter).second)) != 0) {
DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs); DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
/* destructive file sources are OK if they are empty, because /* destructive file sources are OK if they are empty, because
@ -1380,7 +1379,7 @@ Session::state(bool full_state)
{ {
Glib::RWLock::ReaderLock dl (diskstream_lock); Glib::RWLock::ReaderLock dl (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if (!(*i)->hidden()) { if (!(*i)->hidden()) {
child->add_child_nocopy ((*i)->get_state()); child->add_child_nocopy ((*i)->get_state());
} }
@ -1511,7 +1510,7 @@ Session::set_state (const XMLNode& node)
Options Options
Sources Sources
AudioRegions AudioRegions
DiskStreams AudioDiskstreams
Connections Connections
Locations Locations
Routes Routes
@ -1745,6 +1744,7 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
const XMLProperty* prop; const XMLProperty* prop;
id_t s_id; id_t s_id;
Source* source; Source* source;
AudioSource* as;
AudioRegion::SourceList sources; AudioRegion::SourceList sources;
uint32_t nchans = 1; uint32_t nchans = 1;
char buf[128]; char buf[128];
@ -1772,7 +1772,13 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
return 0; return 0;
} }
sources.push_back(source); as = dynamic_cast<AudioSource*>(source);
if (!as) {
error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
return 0;
}
sources.push_back (as);
/* pickup other channels */ /* pickup other channels */
@ -1785,7 +1791,13 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg; error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
return 0; return 0;
} }
sources.push_back(source);
as = dynamic_cast<AudioSource*>(source);
if (!as) {
error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
return 0;
}
sources.push_back (as);
} }
} }
@ -1804,12 +1816,14 @@ Session::get_sources_as_xml ()
{ {
XMLNode* node = new XMLNode (X_("Sources")); XMLNode* node = new XMLNode (X_("Sources"));
Glib::Mutex::Lock lm (source_lock); Glib::Mutex::Lock lm (audio_source_lock);
for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) { for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
node->add_child_nocopy ((*i).second->get_state()); node->add_child_nocopy ((*i).second->get_state());
} }
/* XXX get MIDI and other sources here */
return *node; return *node;
} }
@ -1867,23 +1881,12 @@ Session::XMLSourceFactory (const XMLNode& node)
} }
try { try {
if (node.property (X_("destructive")) != 0) { src = AudioFileSource::create (node);
src = new DestructiveFileSource (node, frame_rate());
} else {
src = new FileSource (node, frame_rate());
}
} }
catch (failed_constructor& err) { catch (failed_constructor& err) {
error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
try { return 0;
src = ExternalSource::create (node);
}
catch (failed_constructor& err) {
error << _("Found a sound file that cannot be used by Ardour. See the progammers.") << endmsg;
return 0;
}
} }
return src; return src;
@ -2930,9 +2933,9 @@ Session::cleanup_sources (Session::cleanup_report& rep)
rep.paths.clear (); rep.paths.clear ();
rep.space = 0; rep.space = 0;
for (SourceList::iterator i = sources.begin(); i != sources.end(); ) { for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
SourceList::iterator tmp; AudioSourceList::iterator tmp;
tmp = i; tmp = i;
++tmp; ++tmp;
@ -2949,7 +2952,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
adding it to the list of all sources below adding it to the list of all sources below
*/ */
sources.erase (i); audio_sources.erase (i);
} }
i = tmp; i = tmp;
@ -3013,20 +3016,17 @@ Session::cleanup_sources (Session::cleanup_report& rep)
state file on disk still references sources we may have already state file on disk still references sources we may have already
dropped. dropped.
*/ */
find_all_sources_across_snapshots (all_sources, true); find_all_sources_across_snapshots (all_sources, true);
/* add our current source list /* add our current source list
*/ */
for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) { for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
FileSource* fs; AudioFileSource* fs;
ExternalSource* sfs;
if ((fs = dynamic_cast<FileSource*> ((*i).second)) != 0) { if ((fs = dynamic_cast<AudioFileSource*> ((*i).second)) != 0) {
all_sources.insert (fs->path()); all_sources.insert (fs->path());
} else if ((sfs = dynamic_cast<ExternalSource*> ((*i).second)) != 0) {
all_sources.insert (sfs->path());
} }
} }

View file

@ -32,6 +32,7 @@
#include <ardour/audioengine.h> #include <ardour/audioengine.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/tempo.h> #include <ardour/tempo.h>
#include <ardour/audiofilesource.h>
#include "i18n.h" #include "i18n.h"
@ -91,6 +92,9 @@ Session::set_smpte_offset (jack_nframes_t off)
{ {
_smpte_offset = off; _smpte_offset = off;
last_smpte_valid = false; last_smpte_valid = false;
AudioFileSource::set_header_position_offset (_smpte_offset, _smpte_offset_negative);
SMPTEOffsetChanged (); /* EMIT SIGNAL */ SMPTEOffsetChanged (); /* EMIT SIGNAL */
} }
@ -99,6 +103,9 @@ Session::set_smpte_offset_negative (bool neg)
{ {
_smpte_offset_negative = neg; _smpte_offset_negative = neg;
last_smpte_valid = false; last_smpte_valid = false;
AudioFileSource::set_header_position_offset (_smpte_offset, _smpte_offset_negative);
SMPTEOffsetChanged (); /* EMIT SIGNAL */ SMPTEOffsetChanged (); /* EMIT SIGNAL */
} }
@ -558,7 +565,7 @@ void
Session::sample_to_smpte( jack_nframes_t sample, SMPTE_Time& smpte, bool use_offset, bool use_subframes ) const Session::sample_to_smpte( jack_nframes_t sample, SMPTE_Time& smpte, bool use_offset, bool use_subframes ) const
{ {
jack_nframes_t offset_sample; jack_nframes_t offset_sample;
if (!use_offset) { if (!use_offset) {
offset_sample = sample; offset_sample = sample;
smpte.negative = false; smpte.negative = false;
@ -690,7 +697,7 @@ Session::smpte_duration_string (char* buf, jack_nframes_t when) const
SMPTE_Time smpte; SMPTE_Time smpte;
smpte_duration (when, smpte); smpte_duration (when, smpte);
snprintf (buf, sizeof (buf), "%02ld:%02ld:%02ld:%02ld", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames); snprintf (buf, sizeof (buf), "%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32, smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
} }
void void

View file

@ -27,7 +27,6 @@
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>
#include <ardour/filesource.h>
#include <ardour/sndfilesource.h> #include <ardour/sndfilesource.h>
#include "i18n.h" #include "i18n.h"
@ -80,7 +79,10 @@ Session::tempoize_region (TimeStretchRequest& tsr)
} }
try { try {
sources.push_back(new FileSource (path, frame_rate(), false, Config->get_native_file_data_format())); sources.push_back (new SndFileSource (path,
Config->get_native_file_data_format(),
Config->get_native_file_header_format(),
frame_rate()));
} catch (failed_constructor& err) { } catch (failed_constructor& err) {
error << string_compose (_("tempoize: error creating new audio file %1 (%2)"), path, strerror (errno)) << endmsg; error << string_compose (_("tempoize: error creating new audio file %1 (%2)"), path, strerror (errno)) << endmsg;
goto out; goto out;
@ -150,13 +152,16 @@ Session::tempoize_region (TimeStretchRequest& tsr)
xnow = localtime (&now); xnow = localtime (&now);
for (it = sources.begin(); it != sources.end(); ++it) { for (it = sources.begin(); it != sources.end(); ++it) {
dynamic_cast<FileSource*>(*it)->update_header (tsr.region->position(), *xnow, now); AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*it);
if (afs) {
afs->update_header (tsr.region->position(), *xnow, now);
}
} }
region_name = tsr.region->name() + X_(".t"); region_name = tsr.region->name() + X_(".t");
r = new AudioRegion (sources, 0, sources.front()->length(), region_name, r = new AudioRegion (sources, 0, sources.front()->length(), region_name,
0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile)); 0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile));
out: out:

View file

@ -36,7 +36,7 @@
#include <ardour/ardour.h> #include <ardour/ardour.h>
#include <ardour/audioengine.h> #include <ardour/audioengine.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/auditioner.h> #include <ardour/auditioner.h>
#include <ardour/slave.h> #include <ardour/slave.h>
#include <ardour/location.h> #include <ardour/location.h>
@ -78,7 +78,7 @@ Session::request_transport_speed (float speed)
} }
void void
Session::request_diskstream_speed (DiskStream& ds, float speed) Session::request_diskstream_speed (AudioDiskstream& ds, float speed)
{ {
Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed); Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
ev->set_ptr (&ds); ev->set_ptr (&ds);
@ -200,7 +200,7 @@ Session::butler_transport_work ()
} }
if (post_transport_work & PostTransportInputChange) { if (post_transport_work & PostTransportInputChange) {
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
(*i)->non_realtime_input_change (); (*i)->non_realtime_input_change ();
} }
} }
@ -216,7 +216,7 @@ Session::butler_transport_work ()
cumulative_rf_motion = 0; cumulative_rf_motion = 0;
reset_rf_scale (0); reset_rf_scale (0);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if (!(*i)->hidden()) { if (!(*i)->hidden()) {
if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) { if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
(*i)->seek ((jack_nframes_t) (_transport_frame * (double) (*i)->speed())); (*i)->seek ((jack_nframes_t) (_transport_frame * (double) (*i)->speed()));
@ -248,7 +248,7 @@ Session::non_realtime_set_speed ()
{ {
Glib::RWLock::ReaderLock lm (diskstream_lock); Glib::RWLock::ReaderLock lm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
(*i)->non_realtime_set_speed (); (*i)->non_realtime_set_speed ();
} }
} }
@ -258,7 +258,7 @@ Session::non_realtime_overwrite ()
{ {
Glib::RWLock::ReaderLock lm (diskstream_lock); Glib::RWLock::ReaderLock lm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if ((*i)->pending_overwrite) { if ((*i)->pending_overwrite) {
(*i)->overwrite_existing_buffers (); (*i)->overwrite_existing_buffers ();
} }
@ -274,7 +274,7 @@ Session::non_realtime_stop (bool abort)
did_record = false; did_record = false;
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if ((*i)->get_captured_frames () != 0) { if ((*i)->get_captured_frames () != 0) {
did_record = true; did_record = true;
break; break;
@ -327,7 +327,7 @@ Session::non_realtime_stop (bool abort)
_have_captured = true; _have_captured = true;
} }
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
(*i)->transport_stopped (*now, xnow, abort); (*i)->transport_stopped (*now, xnow, abort);
} }
@ -364,7 +364,7 @@ Session::non_realtime_stop (bool abort)
} }
#endif #endif
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if (!(*i)->hidden()) { if (!(*i)->hidden()) {
if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) { if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
(*i)->seek ((jack_nframes_t) (_transport_frame * (double) (*i)->speed())); (*i)->seek ((jack_nframes_t) (_transport_frame * (double) (*i)->speed()));
@ -491,7 +491,7 @@ Session::set_auto_loop (bool yn)
if (seamless_loop) { if (seamless_loop) {
// set all diskstreams to use internal looping // set all diskstreams to use internal looping
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if (!(*i)->hidden()) { if (!(*i)->hidden()) {
(*i)->set_loop (loc); (*i)->set_loop (loc);
} }
@ -499,7 +499,7 @@ Session::set_auto_loop (bool yn)
} }
else { else {
// set all diskstreams to NOT use internal looping // set all diskstreams to NOT use internal looping
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if (!(*i)->hidden()) { if (!(*i)->hidden()) {
(*i)->set_loop (0); (*i)->set_loop (0);
} }
@ -529,7 +529,7 @@ Session::set_auto_loop (bool yn)
clear_events (Event::AutoLoop); clear_events (Event::AutoLoop);
// set all diskstreams to NOT use internal looping // set all diskstreams to NOT use internal looping
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if (!(*i)->hidden()) { if (!(*i)->hidden()) {
(*i)->set_loop (0); (*i)->set_loop (0);
} }
@ -645,7 +645,7 @@ Session::locate (jack_nframes_t target_frame, bool with_roll, bool with_flush, b
The rarity and short potential lock duration makes this "OK" The rarity and short potential lock duration makes this "OK"
*/ */
Glib::RWLock::ReaderLock dsm (diskstream_lock); Glib::RWLock::ReaderLock dsm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if ((*i)->record_enabled ()) { if ((*i)->record_enabled ()) {
//cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl; //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (!auto_input); (*i)->monitor_input (!auto_input);
@ -660,7 +660,7 @@ Session::locate (jack_nframes_t target_frame, bool with_roll, bool with_flush, b
The rarity and short potential lock duration makes this "OK" The rarity and short potential lock duration makes this "OK"
*/ */
Glib::RWLock::ReaderLock dsm (diskstream_lock); Glib::RWLock::ReaderLock dsm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if ((*i)->record_enabled ()) { if ((*i)->record_enabled ()) {
//cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl; //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (true); (*i)->monitor_input (true);
@ -704,7 +704,7 @@ Session::set_transport_speed (float speed, bool abort)
The rarity and short potential lock duration makes this "OK" The rarity and short potential lock duration makes this "OK"
*/ */
Glib::RWLock::ReaderLock dsm (diskstream_lock); Glib::RWLock::ReaderLock dsm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if ((*i)->record_enabled ()) { if ((*i)->record_enabled ()) {
//cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl; //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (true); (*i)->monitor_input (true);
@ -730,7 +730,7 @@ Session::set_transport_speed (float speed, bool abort)
The rarity and short potential lock duration makes this "OK" The rarity and short potential lock duration makes this "OK"
*/ */
Glib::RWLock::ReaderLock dsm (diskstream_lock); Glib::RWLock::ReaderLock dsm (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if (auto_input && (*i)->record_enabled ()) { if (auto_input && (*i)->record_enabled ()) {
//cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl; //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (false); (*i)->monitor_input (false);
@ -781,7 +781,7 @@ Session::set_transport_speed (float speed, bool abort)
_last_transport_speed = _transport_speed; _last_transport_speed = _transport_speed;
_transport_speed = speed; _transport_speed = speed;
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if ((*i)->realtime_set_speed ((*i)->speed(), true)) { if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed); post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
} }
@ -871,7 +871,7 @@ Session::actually_start_transport ()
transport_sub_state |= PendingDeclickIn; transport_sub_state |= PendingDeclickIn;
_transport_speed = 1.0; _transport_speed = 1.0;
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
(*i)->realtime_set_speed ((*i)->speed(), true); (*i)->realtime_set_speed ((*i)->speed(), true);
} }
@ -1001,7 +1001,7 @@ Session::set_slave_source (SlaveSource src, jack_nframes_t frame)
_slave_type = src; _slave_type = src;
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
if (!(*i)->hidden()) { if (!(*i)->hidden()) {
if ((*i)->realtime_set_speed ((*i)->speed(), true)) { if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
non_rt_required = true; non_rt_required = true;
@ -1033,7 +1033,7 @@ Session::reverse_diskstream_buffers ()
} }
void void
Session::set_diskstream_speed (DiskStream* stream, float speed) Session::set_diskstream_speed (AudioDiskstream* stream, float speed)
{ {
if (stream->realtime_set_speed (speed, false)) { if (stream->realtime_set_speed (speed, false)) {
post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed); post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
@ -1229,7 +1229,7 @@ Session::update_latency_compensation (bool with_stop, bool abort)
/* reflect any changes in latencies into capture offsets /* reflect any changes in latencies into capture offsets
*/ */
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
(*i)->set_capture_offset (); (*i)->set_capture_offset ();
} }
} }

View file

@ -18,47 +18,203 @@
$Id$ $Id$
*/ */
#include <cerrno>
#include <climits>
#include <pwd.h>
#include <sys/utsname.h>
#include <glibmm/miscutils.h>
#include <ardour/sndfilesource.h> #include <ardour/sndfilesource.h>
#include "i18n.h" #include "i18n.h"
using namespace std;
using namespace ARDOUR; using namespace ARDOUR;
SndFileSource::SndFileSource (const XMLNode& node) SndFileSource::SndFileSource (const XMLNode& node)
: ExternalSource (node) : AudioFileSource (node)
{ {
init (_name, true); init (_name);
SourceCreated (this); /* EMIT SIGNAL */
if (open()) {
throw failed_constructor ();
}
if (_build_peakfiles) {
if (initialize_peakfile (false, _path)) {
sf_close (sf);
sf = 0;
throw failed_constructor ();
}
}
AudioSourceCreated (this); /* EMIT SIGNAL */
} }
SndFileSource::SndFileSource (const string& idstr, bool build_peak) SndFileSource::SndFileSource (string idstr, Flag flags)
: ExternalSource(idstr, build_peak) : AudioFileSource (idstr, Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy)))
{ {
init (idstr, build_peak); init (idstr);
if (build_peak) { if (open()) {
SourceCreated (this); /* EMIT SIGNAL */ throw failed_constructor ();
} }
if (_build_peakfiles) {
if (initialize_peakfile (false, _path)) {
sf_close (sf);
sf = 0;
throw failed_constructor ();
}
}
AudioSourceCreated (this); /* EMIT SIGNAL */
}
SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf, jack_nframes_t rate, Flag flags)
: AudioFileSource(idstr, flags, sfmt, hf)
{
int fmt = 0;
init (idstr);
cerr << "creating " << idstr << " hf = " << hf << endl;
switch (hf) {
case CAF:
fmt = SF_FORMAT_CAF;
_flags = Flag (_flags & ~Broadcast);
break;
case AIFF:
fmt = SF_FORMAT_AIFF;
_flags = Flag (_flags & ~Broadcast);
break;
case BWF:
fmt = SF_FORMAT_WAV;
_flags = Flag (_flags | Broadcast);
break;
case WAVE:
fmt = SF_FORMAT_WAV;
_flags = Flag (_flags & ~Broadcast);
break;
case WAVE64:
fmt = SF_FORMAT_W64;
_flags = Flag (_flags & ~Broadcast);
break;
default:
fatal << string_compose (_("programming error: %1"), X_("unsupported audio header format requested")) << endmsg;
/*NOTREACHED*/
break;
}
switch (sfmt) {
case FormatFloat:
fmt |= SF_FORMAT_FLOAT;
break;
case FormatInt24:
fmt |= SF_FORMAT_PCM_24;
break;
}
_info.channels = 1;
_info.samplerate = rate;
_info.format = fmt;
if (open()) {
throw failed_constructor();
}
if (writable() && (_flags & Broadcast)) {
_broadcast_info = new SF_BROADCAST_INFO;
memset (_broadcast_info, 0, sizeof (*_broadcast_info));
snprintf (_broadcast_info->description, sizeof (_broadcast_info->description), "BWF %s", _name.c_str());
struct utsname utsinfo;
if (uname (&utsinfo)) {
error << string_compose(_("FileSource: cannot get host information for BWF header (%1)"), strerror(errno)) << endmsg;
return;
}
snprintf (_broadcast_info->originator, sizeof (_broadcast_info->originator), "ardour:%s:%s:%s:%s:%s)",
Glib::get_real_name().c_str(),
utsinfo.nodename,
utsinfo.sysname,
utsinfo.release,
utsinfo.version);
_broadcast_info->version = 1;
/* XXX do something about this field */
snprintf (_broadcast_info->umid, sizeof (_broadcast_info->umid), "%s", "fnord");
/* coding history is added by libsndfile */
if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (_broadcast_info)) != SF_TRUE) {
char errbuf[256];
sf_error_str (0, errbuf, sizeof (errbuf) - 1);
error << string_compose (_("cannot set broadcast info for audio file %1 (%2); dropping broadcast info for this file"), _path, errbuf) << endmsg;
_flags = Flag (_flags & ~Broadcast);
delete _broadcast_info;
_broadcast_info = 0;
}
}
if (_build_peakfiles) {
if (initialize_peakfile (false, _path)) {
sf_close (sf);
sf = 0;
throw failed_constructor ();
}
}
/* since SndFileSource's constructed with this constructor can be writable, make sure we update if the header info changes */
if (writable()) {
HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioFileSource::handle_header_position_change));
}
if (_build_peakfiles) {
if (initialize_peakfile (false, _path)) {
sf_close (sf);
sf = 0;
throw failed_constructor ();
}
}
AudioSourceCreated (this); /* EMIT SIGNAL */
} }
void void
SndFileSource::init (const string& idstr, bool build_peak) SndFileSource::init (const string& idstr)
{ {
string::size_type pos; string::size_type pos;
string file; string file;
tmpbuf = 0; interleave_buf = 0;
tmpbufsize = 0; interleave_bufsize = 0;
sf = 0; sf = 0;
_broadcast_info = 0;
_name = idstr;
if ((pos = idstr.find_last_of (':')) == string::npos) { if ((pos = idstr.find_last_of (':')) == string::npos) {
channel = 0; channel = 0;
file = idstr; _name = Glib::path_get_basename (idstr);
} else { } else {
channel = atoi (idstr.substr (pos+1).c_str()); channel = atoi (idstr.substr (pos+1).c_str());
file = idstr.substr (0, pos); _name = Glib::path_get_basename (idstr.substr (0, pos));
} }
/* although libsndfile says we don't need to set this, /* although libsndfile says we don't need to set this,
@ -66,46 +222,56 @@ SndFileSource::init (const string& idstr, bool build_peak)
*/ */
memset (&_info, 0, sizeof(_info)); memset (&_info, 0, sizeof(_info));
}
/* note that we temporarily truncated _id at the colon */ int
SndFileSource::open ()
if ((sf = sf_open (file.c_str(), SFM_READ, &_info)) == 0) { {
if ((sf = sf_open (_path.c_str(), (writable() ? SFM_RDWR : SFM_READ), &_info)) == 0) {
char errbuf[256]; char errbuf[256];
sf_error_str (0, errbuf, sizeof (errbuf) - 1); sf_error_str (0, errbuf, sizeof (errbuf) - 1);
error << string_compose(_("SndFileSource: cannot open file \"%1\" (%2)"), file, errbuf) << endmsg; error << string_compose(_("SndFileSource: cannot open file \"%1\" for %2 (%3)"),
throw failed_constructor(); _path, (writable() ? "read+write" : "reading"), errbuf) << endmsg;
return -1;
} }
if (channel >= _info.channels) { if (channel >= _info.channels) {
error << string_compose(_("SndFileSource: file only contains %1 channels; %2 is invalid as a channel number"), _info.channels, channel) << endmsg; error << string_compose(_("SndFileSource: file only contains %1 channels; %2 is invalid as a channel number"), _info.channels, channel) << endmsg;
sf_close (sf); sf_close (sf);
sf = 0; sf = 0;
throw failed_constructor(); return -1;
} }
_length = _info.frames; _length = _info.frames;
_path = file;
if (build_peak) { if (writable()) {
if (initialize_peakfile (false, _path)) { sf_command (sf, SFC_SET_UPDATE_HEADER_AUTO, 0, SF_FALSE);
sf_close (sf); }
sf = 0;
throw failed_constructor (); return 0;
} }
void
SndFileSource::close ()
{
if (sf) {
sf_close (sf);
sf = 0;
} }
} }
SndFileSource::~SndFileSource () SndFileSource::~SndFileSource ()
{ {
GoingAway (this); /* EMIT SIGNAL */ GoingAway (this); /* EMIT SIGNAL */
if (sf) { close ();
sf_close (sf);
if (interleave_buf) {
delete [] interleave_buf;
} }
if (tmpbuf) { if (_broadcast_info) {
delete [] tmpbuf; delete [] _broadcast_info;
} }
} }
@ -116,49 +282,73 @@ SndFileSource::sample_rate () const
} }
jack_nframes_t jack_nframes_t
SndFileSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const SndFileSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
{ {
int32_t nread; int32_t nread;
float *ptr; float *ptr;
uint32_t real_cnt; uint32_t real_cnt;
jack_nframes_t file_cnt;
if (sf_seek (sf, (off_t) start, SEEK_SET) < 0) { if (start > _length) {
char errbuf[256];
sf_error_str (0, errbuf, sizeof (errbuf) - 1); /* read starts beyond end of data, just memset to zero */
error << string_compose(_("SndFileSource: could not seek to frame %1 within %2 (%3)"), start, _name.substr (1), errbuf) << endmsg;
return 0; file_cnt = 0;
} else if (start + cnt > _length) {
/* read ends beyond end of data, read some, memset the rest */
file_cnt = _length - start;
} else {
/* read is entirely within data */
file_cnt = cnt;
}
if (file_cnt) {
if (sf_seek (sf, (off_t) start, SEEK_SET) < 0) {
char errbuf[256];
sf_error_str (0, errbuf, sizeof (errbuf) - 1);
error << string_compose(_("SndFileSource: could not seek to frame %1 within %2 (%3)"), start, _name.substr (1), errbuf) << endmsg;
return 0;
}
if (_info.channels == 1) {
jack_nframes_t ret = sf_read_float (sf, dst, file_cnt);
_read_data_count = cnt * sizeof(float);
return ret;
}
} }
if (_info.channels == 1) { if (file_cnt != cnt) {
jack_nframes_t ret = sf_read_float (sf, dst, cnt); jack_nframes_t delta = cnt - file_cnt;
_read_data_count = cnt * sizeof(float); memset (dst+file_cnt, 0, sizeof (Sample) * delta);
return ret;
} }
real_cnt = cnt * _info.channels; real_cnt = cnt * _info.channels;
{ if (interleave_bufsize < real_cnt) {
Glib::Mutex::Lock lm (_tmpbuf_lock);
if (tmpbufsize < real_cnt) { if (interleave_buf) {
delete [] interleave_buf;
if (tmpbuf) {
delete [] tmpbuf;
}
tmpbufsize = real_cnt;
tmpbuf = new float[tmpbufsize];
}
nread = sf_read_float (sf, tmpbuf, real_cnt);
ptr = tmpbuf + channel;
nread /= _info.channels;
/* stride through the interleaved data */
for (int32_t n = 0; n < nread; ++n) {
dst[n] = *ptr;
ptr += _info.channels;
} }
interleave_bufsize = real_cnt;
interleave_buf = new float[interleave_bufsize];
}
nread = sf_read_float (sf, interleave_buf, real_cnt);
ptr = interleave_buf + channel;
nread /= _info.channels;
/* stride through the interleaved data */
for (int32_t n = 0; n < nread; ++n) {
dst[n] = *ptr;
ptr += _info.channels;
} }
_read_data_count = cnt * sizeof(float); _read_data_count = cnt * sizeof(float);
@ -166,3 +356,163 @@ SndFileSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char
return nread; return nread;
} }
jack_nframes_t
SndFileSource::write_unlocked (Sample *data, jack_nframes_t cnt, char * workbuf)
{
if (!writable()) {
return 0;
}
if (_info.channels != 1) {
fatal << string_compose (_("programming error: %1 %2"), X_("SndFileSource::write called on non-mono file"), _path) << endmsg;
/*NOTREACHED*/
return 0;
}
jack_nframes_t oldlen;
int32_t frame_pos = _length;
if (write_float (data, frame_pos, cnt) != cnt) {
return 0;
}
oldlen = _length;
update_length (oldlen, cnt);
if (_build_peakfiles) {
PeakBuildRecord *pbr = 0;
if (pending_peak_builds.size()) {
pbr = pending_peak_builds.back();
}
if (pbr && pbr->frame + pbr->cnt == oldlen) {
/* the last PBR extended to the start of the current write,
so just extend it again.
*/
pbr->cnt += cnt;
} else {
pending_peak_builds.push_back (new PeakBuildRecord (oldlen, cnt));
}
_peaks_built = false;
}
if (_build_peakfiles) {
queue_for_peaks (*this);
}
_write_data_count = cnt;
return cnt;
}
int
SndFileSource::update_header (jack_nframes_t when, struct tm& now, time_t tnow)
{
/* allow derived classes to override how this is done */
set_timeline_position (when);
if (_flags & Broadcast) {
/* this will flush the header implicitly */
return setup_broadcast_info (when, now, tnow);
} else {
return flush_header ();
}
}
int
SndFileSource::flush_header ()
{
return (sf_command (sf, SFC_UPDATE_HEADER_NOW, 0, 0) != SF_TRUE);
}
int
SndFileSource::setup_broadcast_info (jack_nframes_t when, struct tm& now, time_t tnow)
{
/* random code is 9 digits */
int random_code = random() % 999999999;
snprintf (_broadcast_info->originator_reference, sizeof (_broadcast_info->originator_reference), "%2s%3s%12s%02d%02d%02d%9d",
bwf_country_code,
bwf_organization_code,
bwf_serial_number,
now.tm_hour,
now.tm_min,
now.tm_sec,
random_code);
snprintf (_broadcast_info->origination_date, sizeof (_broadcast_info->origination_date), "%4d-%02d-%02d",
1900 + now.tm_year,
now.tm_mon,
now.tm_mday);
snprintf (_broadcast_info->origination_time, sizeof (_broadcast_info->origination_time), "%02d-%02d-%02d",
now.tm_hour,
now.tm_min,
now.tm_sec);
/* now update header position taking header offset into account */
set_header_timeline_position ();
/* note that libsndfile flushes the header to disk when resetting the broadcast info */
if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) {
error << string_compose (_("cannot set broadcast info for audio file %1; Dropping broadcast info for this file"), _path) << endmsg;
_flags = Flag (_flags & ~Broadcast);
delete _broadcast_info;
_broadcast_info = 0;
return -1;
}
return 0;
}
void
SndFileSource::set_header_timeline_position ()
{
uint64_t pos;
_broadcast_info->time_reference_high = 0;
if (header_position_negative) {
if (ULONG_LONG_MAX - header_position_offset < timeline_position) {
pos = ULONG_LONG_MAX; // impossible
} else {
pos = timeline_position + header_position_offset;
}
} else {
if (timeline_position < header_position_offset) {
pos = 0;
} else {
pos = timeline_position - header_position_offset;
}
}
_broadcast_info->time_reference_high = (pos >> 32);
_broadcast_info->time_reference_low = (pos & 0xffffffff);
}
jack_nframes_t
SndFileSource::write_float (Sample* data, jack_nframes_t frame_pos, jack_nframes_t cnt)
{
if (sf_seek (sf, frame_pos, SEEK_SET) != frame_pos) {
error << string_compose (_("%1: cannot seek to %2"), _path, frame_pos) << endmsg;
return 0;
}
if (sf_writef_float (sf, data, cnt) != (ssize_t) cnt) {
return 0;
}
return cnt;
}

View file

@ -42,35 +42,18 @@ using std::max;
using namespace ARDOUR; using namespace ARDOUR;
sigc::signal<void,Source *> Source::SourceCreated; Source::Source (string name)
pthread_t Source::peak_thread;
bool Source::have_peak_thread = false;
vector<Source*> Source::pending_peak_sources;
Glib::StaticMutex Source::pending_peak_sources_lock = GLIBMM_STATIC_MUTEX_INIT;
int Source::peak_request_pipe[2];
bool Source::_build_missing_peakfiles = false;
bool Source::_build_peakfiles = false;
Source::Source (bool announce)
{ {
_name = name;
_id = ARDOUR::new_id(); _id = ARDOUR::new_id();
_use_cnt = 0; _use_cnt = 0;
_peaks_built = false;
next_peak_clear_should_notify = true;
_timestamp = 0; _timestamp = 0;
_read_data_count = 0;
_write_data_count = 0;
} }
Source::Source (const XMLNode& node) Source::Source (const XMLNode& node)
{ {
_use_cnt = 0; _use_cnt = 0;
_peaks_built = false;
next_peak_clear_should_notify = true;
_timestamp = 0; _timestamp = 0;
_read_data_count = 0;
_write_data_count = 0;
if (set_state (node)) { if (set_state (node)) {
throw failed_constructor(); throw failed_constructor();
@ -96,10 +79,6 @@ Source::get_state ()
node->add_property ("timestamp", buf); node->add_property ("timestamp", buf);
} }
if (_captured_for.length()) {
node->add_property ("captured-for", _captured_for);
}
return *node; return *node;
} }
@ -124,734 +103,9 @@ Source::set_state (const XMLNode& node)
sscanf (prop->value().c_str(), "%ld", &_timestamp); sscanf (prop->value().c_str(), "%ld", &_timestamp);
} }
if ((prop = node.property ("captured-for")) != 0) {
_captured_for = prop->value();
}
return 0; return 0;
} }
/***********************************************************************
PEAK FILE STUFF
***********************************************************************/
void*
Source::peak_thread_work (void* arg)
{
PBD::ThreadCreated (pthread_self(), X_("Peak"));
struct pollfd pfd[1];
Glib::Mutex::Lock lm (pending_peak_sources_lock);
while (true) {
pfd[0].fd = peak_request_pipe[0];
pfd[0].events = POLLIN|POLLERR|POLLHUP;
pending_peak_sources_lock.unlock();
if (poll (pfd, 1, -1) < 0) {
if (errno == EINTR) {
pending_peak_sources_lock.lock();
continue;
}
error << string_compose (_("poll on peak request pipe failed (%1)"),
strerror (errno))
<< endmsg;
break;
}
if (pfd[0].revents & ~POLLIN) {
error << _("Error on peak thread request pipe") << endmsg;
break;
}
if (pfd[0].revents & POLLIN) {
char req;
/* empty the pipe of all current requests */
while (1) {
size_t nread = ::read (peak_request_pipe[0], &req, sizeof (req));
if (nread == 1) {
switch ((PeakRequest::Type) req) {
case PeakRequest::Build:
break;
case PeakRequest::Quit:
pthread_exit_pbd (0);
/*NOTREACHED*/
break;
default:
break;
}
} else if (nread == 0) {
break;
} else if (errno == EAGAIN) {
break;
} else {
fatal << _("Error reading from peak request pipe") << endmsg;
/*NOTREACHED*/
}
}
}
pending_peak_sources_lock.lock();
while (!pending_peak_sources.empty()) {
Source* s = pending_peak_sources.front();
pending_peak_sources.erase (pending_peak_sources.begin());
pending_peak_sources_lock.unlock();
s->build_peaks();
pending_peak_sources_lock.lock();
}
}
pthread_exit_pbd (0);
/*NOTREACHED*/
return 0;
}
int
Source::start_peak_thread ()
{
if (!_build_peakfiles) {
return 0;
}
if (pipe (peak_request_pipe)) {
error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
return -1;
}
if (fcntl (peak_request_pipe[0], F_SETFL, O_NONBLOCK)) {
error << string_compose(_("UI: cannot set O_NONBLOCK on peak request pipe (%1)"), strerror (errno)) << endmsg;
return -1;
}
if (fcntl (peak_request_pipe[1], F_SETFL, O_NONBLOCK)) {
error << string_compose(_("UI: cannot set O_NONBLOCK on peak request pipe (%1)"), strerror (errno)) << endmsg;
return -1;
}
if (pthread_create_and_store ("peak file builder", &peak_thread, 0, peak_thread_work, 0)) {
error << _("Source: could not create peak thread") << endmsg;
return -1;
}
have_peak_thread = true;
return 0;
}
void
Source::stop_peak_thread ()
{
if (!have_peak_thread) {
return;
}
void* status;
char c = (char) PeakRequest::Quit;
::write (peak_request_pipe[1], &c, 1);
pthread_join (peak_thread, &status);
}
void
Source::queue_for_peaks (Source& source)
{
if (have_peak_thread) {
Glib::Mutex::Lock lm (pending_peak_sources_lock);
source.next_peak_clear_should_notify = true;
if (find (pending_peak_sources.begin(),
pending_peak_sources.end(),
&source) == pending_peak_sources.end()) {
pending_peak_sources.push_back (&source);
}
char c = (char) PeakRequest::Build;
::write (peak_request_pipe[1], &c, 1);
}
}
void Source::clear_queue_for_peaks ()
{
/* this is done to cancel a group of running peak builds */
if (have_peak_thread) {
Glib::Mutex::Lock lm (pending_peak_sources_lock);
pending_peak_sources.clear ();
}
}
bool
Source::peaks_ready (sigc::slot<void> the_slot, sigc::connection& conn) const
{
bool ret;
Glib::Mutex::Lock lm (_lock);
/* check to see if the peak data is ready. if not
connect the slot while still holding the lock.
*/
if (!(ret = _peaks_built)) {
conn = PeaksReady.connect (the_slot);
}
return ret;
}
int
Source::rename_peakfile (string newpath)
{
/* caller must hold _lock */
string oldpath = peakpath;
if (access (oldpath.c_str(), F_OK) == 0) {
if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
error << string_compose (_("cannot rename peakfile for %1 from %2 to %3 (%4)"), _name, oldpath, newpath, strerror (errno)) << endmsg;
return -1;
}
}
peakpath = newpath;
return 0;
}
int
Source::initialize_peakfile (bool newfile, string audio_path)
{
struct stat statbuf;
peakpath = peak_path (audio_path);
if (newfile) {
if (!_build_peakfiles) {
return 0;
}
_peaks_built = false;
} else {
if (stat (peakpath.c_str(), &statbuf)) {
if (errno != ENOENT) {
/* it exists in the peaks dir, but there is some kind of error */
error << string_compose(_("Source: cannot stat peakfile \"%1\""), peakpath) << endmsg;
return -1;
}
} else {
/* we found it in the peaks dir */
}
if (statbuf.st_size == 0) {
_peaks_built = false;
} else {
// Check if the audio file has changed since the peakfile was built.
struct stat stat_file;
int err = stat (audio_path.c_str(), &stat_file);
if (!err && stat_file.st_mtime > statbuf.st_mtime){
_peaks_built = false;
} else {
_peaks_built = true;
}
}
}
if (!newfile && !_peaks_built && _build_missing_peakfiles && _build_peakfiles) {
build_peaks_from_scratch ();
}
return 0;
}
int
Source::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start, jack_nframes_t cnt, double samples_per_visual_peak) const
{
Glib::Mutex::Lock lm (_lock);
double scale;
double expected_peaks;
PeakData::PeakDatum xmax;
PeakData::PeakDatum xmin;
int32_t to_read;
uint32_t nread;
jack_nframes_t zero_fill = 0;
int ret = -1;
PeakData* staging = 0;
Sample* raw_staging = 0;
char * workbuf = 0;
int peakfile = -1;
expected_peaks = (cnt / (double) frames_per_peak);
scale = npeaks/expected_peaks;
#if 0
cerr << "======>RP: npeaks = " << npeaks
<< " start = " << start
<< " cnt = " << cnt
<< " len = " << _length
<< " samples_per_visual_peak =" << samples_per_visual_peak
<< " expected was " << expected_peaks << " ... scale = " << scale
<< " PD ptr = " << peaks
<<endl;
#endif
/* fix for near-end-of-file conditions */
if (cnt > _length - start) {
// cerr << "too close to end @ " << _length << " given " << start << " + " << cnt << endl;
cnt = _length - start;
jack_nframes_t old = npeaks;
npeaks = min ((jack_nframes_t) floor (cnt / samples_per_visual_peak), npeaks);
zero_fill = old - npeaks;
}
// cerr << "actual npeaks = " << npeaks << " zf = " << zero_fill << endl;
if (npeaks == cnt) {
// cerr << "RAW DATA\n";
/* no scaling at all, just get the sample data and duplicate it for
both max and min peak values.
*/
Sample* raw_staging = new Sample[cnt];
workbuf = new char[cnt*4];
if (read_unlocked (raw_staging, start, cnt, workbuf) != cnt) {
error << _("cannot read sample data for unscaled peak computation") << endmsg;
return -1;
}
for (jack_nframes_t i = 0; i < npeaks; ++i) {
peaks[i].max = raw_staging[i];
peaks[i].min = raw_staging[i];
}
delete [] raw_staging;
delete [] workbuf;
return 0;
}
if (scale == 1.0) {
off_t first_peak_byte = (start / frames_per_peak) * sizeof (PeakData);
/* open, read, close */
if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
error << string_compose(_("Source: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
return -1;
}
// cerr << "DIRECT PEAKS\n";
nread = ::pread (peakfile, peaks, sizeof (PeakData)* npeaks, first_peak_byte);
close (peakfile);
if (nread != sizeof (PeakData) * npeaks) {
cerr << "Source["
<< _name
<< "]: cannot read peaks from peakfile! (read only "
<< nread
<< " not "
<< npeaks
<< "at sample "
<< start
<< " = byte "
<< first_peak_byte
<< ')'
<< endl;
return -1;
}
if (zero_fill) {
memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
}
return 0;
}
jack_nframes_t tnp;
if (scale < 1.0) {
// cerr << "DOWNSAMPLE\n";
/* the caller wants:
- more frames-per-peak (lower resolution) than the peakfile, or to put it another way,
- less peaks than the peakfile holds for the same range
So, read a block into a staging area, and then downsample from there.
to avoid confusion, I'll refer to the requested peaks as visual_peaks and the peakfile peaks as stored_peaks
*/
const uint32_t chunksize = (uint32_t) min (expected_peaks, 4096.0);
staging = new PeakData[chunksize];
/* compute the rounded up frame position */
jack_nframes_t current_frame = start;
jack_nframes_t current_stored_peak = (jack_nframes_t) ceil (current_frame / (double) frames_per_peak);
uint32_t next_visual_peak = (uint32_t) ceil (current_frame / samples_per_visual_peak);
double next_visual_peak_frame = next_visual_peak * samples_per_visual_peak;
uint32_t stored_peak_before_next_visual_peak = (jack_nframes_t) next_visual_peak_frame / frames_per_peak;
uint32_t nvisual_peaks = 0;
uint32_t stored_peaks_read = 0;
uint32_t i = 0;
/* handle the case where the initial visual peak is on a pixel boundary */
current_stored_peak = min (current_stored_peak, stored_peak_before_next_visual_peak);
/* open ... close during out: handling */
if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
error << string_compose(_("Source: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
return 0;
}
while (nvisual_peaks < npeaks) {
if (i == stored_peaks_read) {
uint32_t start_byte = current_stored_peak * sizeof(PeakData);
tnp = min ((_length/frames_per_peak - current_stored_peak), (jack_nframes_t) expected_peaks);
to_read = min (chunksize, tnp);
off_t fend = lseek (peakfile, 0, SEEK_END);
if ((nread = ::pread (peakfile, staging, sizeof (PeakData) * to_read, start_byte))
!= sizeof (PeakData) * to_read) {
cerr << "Source["
<< _name
<< "]: cannot read peak data from peakfile ("
<< (nread / sizeof(PeakData))
<< " peaks instead of "
<< to_read
<< ") ("
<< strerror (errno)
<< ')'
<< " at start_byte = " << start_byte
<< " _length = " << _length << " versus len = " << fend
<< " expected maxpeaks = " << (_length - current_frame)/frames_per_peak
<< " npeaks was " << npeaks
<< endl;
goto out;
}
i = 0;
stored_peaks_read = nread / sizeof(PeakData);
}
xmax = -1.0;
xmin = 1.0;
while ((i < stored_peaks_read) && (current_stored_peak <= stored_peak_before_next_visual_peak)) {
xmax = max (xmax, staging[i].max);
xmin = min (xmin, staging[i].min);
++i;
++current_stored_peak;
--expected_peaks;
}
peaks[nvisual_peaks].max = xmax;
peaks[nvisual_peaks].min = xmin;
++nvisual_peaks;
++next_visual_peak;
//next_visual_peak_frame = min ((next_visual_peak * samples_per_visual_peak), (next_visual_peak_frame+samples_per_visual_peak) );
next_visual_peak_frame = min ((double) start+cnt, (next_visual_peak_frame+samples_per_visual_peak) );
stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_frame / frames_per_peak;
}
if (zero_fill) {
memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
}
ret = 0;
} else {
// cerr << "UPSAMPLE\n";
/* the caller wants
- less frames-per-peak (more resolution)
- more peaks than stored in the Peakfile
So, fetch data from the raw source, and generate peak
data on the fly.
*/
jack_nframes_t frames_read = 0;
jack_nframes_t current_frame = start;
jack_nframes_t i = 0;
jack_nframes_t nvisual_peaks = 0;
jack_nframes_t chunksize = (jack_nframes_t) min (cnt, (jack_nframes_t) 4096);
raw_staging = new Sample[chunksize];
workbuf = new char[chunksize *4];
jack_nframes_t frame_pos = start;
double pixel_pos = floor (frame_pos / samples_per_visual_peak);
double next_pixel_pos = ceil (frame_pos / samples_per_visual_peak);
double pixels_per_frame = 1.0 / samples_per_visual_peak;
xmin = 1.0;
xmax = -1.0;
while (nvisual_peaks < npeaks) {
if (i == frames_read) {
to_read = min (chunksize, (_length - current_frame));
if ((frames_read = read_unlocked (raw_staging, current_frame, to_read, workbuf)) < 0) {
error << string_compose(_("Source[%1]: peak read - cannot read %2 samples at offset %3")
, _name, to_read, current_frame)
<< endmsg;
goto out;
}
i = 0;
}
xmax = max (xmax, raw_staging[i]);
xmin = min (xmin, raw_staging[i]);
++i;
++current_frame;
pixel_pos += pixels_per_frame;
if (pixel_pos >= next_pixel_pos) {
peaks[nvisual_peaks].max = xmax;
peaks[nvisual_peaks].min = xmin;
++nvisual_peaks;
xmin = 1.0;
xmax = -1.0;
next_pixel_pos = ceil (pixel_pos + 0.5);
}
}
if (zero_fill) {
memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
}
ret = 0;
}
out:
if (peakfile >= 0) {
close (peakfile);
}
if (staging) {
delete [] staging;
}
if (raw_staging) {
delete [] raw_staging;
}
if (workbuf) {
delete [] workbuf;
}
return ret;
}
#undef DEBUG_PEAK_BUILD
int
Source::build_peaks ()
{
vector<PeakBuildRecord*> built;
int status = -1;
bool pr_signal = false;
list<PeakBuildRecord*> copy;
{
Glib::Mutex::Lock lm (_lock);
copy = pending_peak_builds;
pending_peak_builds.clear ();
}
#ifdef DEBUG_PEAK_BUILD
cerr << "build peaks with " << copy.size() << " requests pending\n";
#endif
for (list<PeakBuildRecord *>::iterator i = copy.begin(); i != copy.end(); ++i) {
if ((status = do_build_peak ((*i)->frame, (*i)->cnt)) != 0) {
unlink (peakpath.c_str());
break;
}
built.push_back (new PeakBuildRecord (*(*i)));
delete *i;
}
{
Glib::Mutex::Lock lm (_lock);
if (status == 0) {
_peaks_built = true;
if (next_peak_clear_should_notify) {
next_peak_clear_should_notify = false;
pr_signal = true;
}
}
}
if (status == 0) {
for (vector<PeakBuildRecord *>::iterator i = built.begin(); i != built.end(); ++i) {
PeakRangeReady ((*i)->frame, (*i)->cnt); /* EMIT SIGNAL */
delete *i;
}
if (pr_signal) {
PeaksReady (); /* EMIT SIGNAL */
}
}
return status;
}
int
Source::do_build_peak (jack_nframes_t first_frame, jack_nframes_t cnt)
{
jack_nframes_t current_frame;
Sample buf[frames_per_peak];
Sample xmin, xmax;
uint32_t peaki;
PeakData* peakbuf;
char * workbuf = 0;
jack_nframes_t frames_read;
jack_nframes_t frames_to_read;
off_t first_peak_byte;
int peakfile = -1;
int ret = -1;
#ifdef DEBUG_PEAK_BUILD
cerr << pthread_self() << ": " << _name << ": building peaks for " << first_frame << " to " << first_frame + cnt - 1 << endl;
#endif
first_peak_byte = (first_frame / frames_per_peak) * sizeof (PeakData);
#ifdef DEBUG_PEAK_BUILD
cerr << "seeking to " << first_peak_byte << " before writing new peak data\n";
#endif
current_frame = first_frame;
peakbuf = new PeakData[(cnt/frames_per_peak)+1];
peaki = 0;
workbuf = new char[max(frames_per_peak, cnt) * 4];
if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
error << string_compose(_("Source: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
return -1;
}
while (cnt) {
frames_to_read = min (frames_per_peak, cnt);
if ((frames_read = read_unlocked (buf, current_frame, frames_to_read, workbuf)) != frames_to_read) {
error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg;
goto out;
}
xmin = buf[0];
xmax = buf[0];
for (jack_nframes_t n = 1; n < frames_read; ++n) {
xmax = max (xmax, buf[n]);
xmin = min (xmin, buf[n]);
// if (current_frame < frames_read) {
// cerr << "sample = " << buf[n] << " max = " << xmax << " min = " << xmin << " max of 2 = " << max (xmax, buf[n]) << endl;
// }
}
peakbuf[peaki].max = xmax;
peakbuf[peaki].min = xmin;
peaki++;
current_frame += frames_read;
cnt -= frames_read;
}
if (::pwrite (peakfile, peakbuf, sizeof (PeakData) * peaki, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaki)) {
error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
goto out;
}
ret = 0;
out:
delete [] peakbuf;
if (peakfile >= 0) {
close (peakfile);
}
if (workbuf)
delete [] workbuf;
return ret;
}
void
Source::build_peaks_from_scratch ()
{
Glib::Mutex::Lock lp (_lock);
next_peak_clear_should_notify = true;
pending_peak_builds.push_back (new PeakBuildRecord (0, _length));
queue_for_peaks (*this);
}
bool
Source::file_changed (string path)
{
struct stat stat_file;
struct stat stat_peak;
int e1 = stat (path.c_str(), &stat_file);
int e2 = stat (peak_path(path).c_str(), &stat_peak);
if (!e1 && !e2 && stat_file.st_mtime > stat_peak.st_mtime){
return true;
} else {
return false;
}
}
void void
Source::use () Source::use ()
{ {
@ -864,30 +118,3 @@ Source::release ()
if (_use_cnt) --_use_cnt; if (_use_cnt) --_use_cnt;
} }
jack_nframes_t
Source::available_peaks (double zoom_factor) const
{
int peakfile;
off_t end;
if (zoom_factor < frames_per_peak) {
return length(); // peak data will come from the audio file
}
/* peak data comes from peakfile */
if ((peakfile = ::open (peakpath.c_str(), O_RDONLY)) < 0) {
error << string_compose(_("Source: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
return 0;
}
{
Glib::Mutex::Lock lm (_lock);
end = lseek (peakfile, 0, SEEK_END);
}
close (peakfile);
return (end/sizeof(PeakData)) * frames_per_peak;
}