summaryrefslogtreecommitdiff
path: root/muse2/muse/audiotrack.cpp
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2012-01-03 17:26:09 +0000
committerFlorian Jung <flo@windfisch.org>2012-01-03 17:26:09 +0000
commit1bc4ba9dfc00b6e7511fbf4765296a2002f83315 (patch)
treedf6a0d5d9b61d64005dd368afea0aea11ab0a6b3 /muse2/muse/audiotrack.cpp
parentb988a0a27bc175ce10bc8fa53ed131486813f3e7 (diff)
merged with release_2_0
Diffstat (limited to 'muse2/muse/audiotrack.cpp')
-rw-r--r--muse2/muse/audiotrack.cpp338
1 files changed, 263 insertions, 75 deletions
diff --git a/muse2/muse/audiotrack.cpp b/muse2/muse/audiotrack.cpp
index aceacc75..e542deec 100644
--- a/muse2/muse/audiotrack.cpp
+++ b/muse2/muse/audiotrack.cpp
@@ -93,7 +93,6 @@ void cacheJackRouteNames()
//---------------------------------------------------------
AudioTrack::AudioTrack(TrackType t)
-//AudioTrack::AudioTrack(TrackType t, int num_out_bufs)
: Track(t)
{
//_totalOutChannels = num_out_bufs; // Is either parameter-default MAX_CHANNELS, or custom value passed (used by syntis).
@@ -111,7 +110,6 @@ AudioTrack::AudioTrack(TrackType t)
addController(new CtrlList(AC_PAN, "Pan", -1.0, 1.0, VAL_LINEAR));
addController(new CtrlList(AC_MUTE,"Mute",0.0,1.0, VAL_LINEAR, true /*dont show in arranger */));
- // Changed by Tim. p3.3.15
//outBuffers = new float*[MAX_CHANNELS];
//for (int i = 0; i < MAX_CHANNELS; ++i)
// outBuffers[i] = new float[MusEGlobal::segmentSize];
@@ -125,7 +123,6 @@ AudioTrack::AudioTrack(TrackType t)
//for (int i = 0; i < MAX_CHANNELS; ++i)
// *(outBuffers + i) = sizeof(float) * MusEGlobal::segmentSize * i;
- // p3.3.38
// Easy way, less desirable... Start out with enough for MAX_CHANNELS. Then multi-channel syntis can re-allocate,
// via a call to (a modified!) setChannels().
// Hard way, more desirable... Creating a synti instance passes the total channels to this constructor, overriding MAX_CHANNELS.
@@ -142,71 +139,181 @@ AudioTrack::AudioTrack(TrackType t)
setVolume(1.0);
}
-//AudioTrack::AudioTrack(const AudioTrack& t)
-// : Track(t)
-AudioTrack::AudioTrack(const AudioTrack& t, bool cloneParts)
- : Track(t, cloneParts)
+AudioTrack::AudioTrack(const AudioTrack& t, int flags)
+ : Track(t, flags)
{
- _totalOutChannels = t._totalOutChannels; // Is either MAX_CHANNELS, or custom value (used by syntis).
_processed = false;
_haveData = false;
- _sendMetronome = t._sendMetronome;
- _controller = t._controller;
- _prefader = t._prefader;
- _auxSend = t._auxSend;
- _efxPipe = new Pipeline(*(t._efxPipe));
- _automationType = t._automationType;
- _inRoutes = t._inRoutes;
- _outRoutes = t._outRoutes;
- // Changed by Tim. p3.3.15
- //outBuffers = new float*[MAX_CHANNELS];
- //for (int i = 0; i < MAX_CHANNELS; ++i)
- // outBuffers[i] = new float[MusEGlobal::segmentSize];
- //for (int i = 0; i < MAX_CHANNELS; ++i)
- // posix_memalign((void**)(outBuffers + i), 16, sizeof(float) * MusEGlobal::segmentSize);
+ _efxPipe = new Pipeline(); // Start off with a new pipeline.
- // p3.3.38
- int chans = _totalOutChannels;
- // Number of allocated buffers is always MAX_CHANNELS or more, even if _totalOutChannels is less.
- if(chans < MAX_CHANNELS)
- chans = MAX_CHANNELS;
- outBuffers = new float*[chans];
- for (int i = 0; i < chans; ++i)
- posix_memalign((void**)&outBuffers[i], 16, sizeof(float) * MusEGlobal::segmentSize);
+ // Don't allocate outBuffers here. Let internal_assign() call setTotalOutChannels to set them up.
+ outBuffers = 0;
+ _totalOutChannels = 0;
+ // This is only set by multi-channel syntis...
+ _totalInChannels = 0;
bufferPos = MAXINT;
- _recFile = t._recFile;
+
+ //_recFile = t._recFile;
+ _recFile = NULL;
+
+ internal_assign(t, flags | ASSIGN_PROPERTIES);
}
+void AudioTrack::internal_assign(const Track& t, int flags)
+{
+ if(t.isMidiTrack())
+ return;
+
+ const AudioTrack& at = (const AudioTrack&)t;
+
+ if(flags & ASSIGN_PROPERTIES)
+ {
+ _sendMetronome = at._sendMetronome;
+ _prefader = at._prefader;
+ _auxSend = at._auxSend;
+ _automationType = at._automationType;
+
+ if(!(flags & ASSIGN_STD_CTRLS))
+ {
+ _controller.clearDelete();
+ for(ciCtrlList icl = at._controller.begin(); icl != at._controller.end(); ++icl)
+ {
+ CtrlList* cl = icl->second;
+ // Copy all built-in controllers (id below AC_PLUGIN_CTL_BASE), but not plugin controllers.
+ if(cl->id() >= AC_PLUGIN_CTL_BASE)
+ continue;
+ CtrlList* new_cl = new CtrlList();
+ new_cl->assign(*cl, CtrlList::ASSIGN_PROPERTIES); // Don't copy values.
+ addController(new_cl);
+ }
+ }
+
+ // This will set up or reallocate the outBuffers.
+ setTotalOutChannels(at._totalOutChannels);
+
+ // This is only set by multi-channel syntis...
+ //_totalInChannels = 0;
+ //_totalInChannels = t._totalInChannels;
+ setTotalInChannels(at._totalInChannels);
+
+ setChannels(at.channels()); // Set track channels (max 2).
+
+ //bufferPos = MAXINT;
+
+ //_recFile = at._recFile;
+ //_recFile = NULL;
+ }
+
+ if(flags & ASSIGN_PLUGINS)
+ {
+ delete _efxPipe;
+ _efxPipe = new Pipeline(*(at._efxPipe)); // Make copies of the plugins.
+ }
+
+ if(flags & (ASSIGN_STD_CTRLS | ASSIGN_PLUGIN_CTRLS))
+ {
+ _controller.clearDelete();
+ for(ciCtrlList icl = at._controller.begin(); icl != at._controller.end(); ++icl)
+ {
+ CtrlList* cl = icl->second;
+ // Discern between built-in controllers (id below AC_PLUGIN_CTL_BASE), and plugin controllers.
+ if(cl->id() >= AC_PLUGIN_CTL_BASE)
+ {
+ if(!(flags & ASSIGN_PLUGIN_CTRLS))
+ continue;
+ }
+ else if(!(flags & ASSIGN_STD_CTRLS))
+ continue;
+
+ CtrlList* new_cl = new CtrlList(*cl); // Let copy constructor handle the rest. Copy values.
+ addController(new_cl);
+ }
+ }
+
+ // FIXME: May get "addRoute: src track route already exists" when say,
+ // an audio output and wave track are selected just because
+ // of the redundancy (wave track wants to connect to output by default).
+ if(flags & ASSIGN_ROUTES)
+ {
+ for(ciRoute ir = at._inRoutes.begin(); ir != at._inRoutes.end(); ++ir)
+ {
+ // Defer all Jack routes to Audio Input and Output copy constructors or assign !
+ if(ir->type == Route::JACK_ROUTE)
+ continue;
+ // Amazingly, this single line seems to work.
+ MusEGlobal::audio->msgAddRoute(*ir, Route(this, ir->channel, ir->channels));
+ }
+
+ for(ciRoute ir = at._outRoutes.begin(); ir != at._outRoutes.end(); ++ir)
+ {
+ // Defer all Jack routes to Audio Input and Output copy constructors or assign !
+ if(ir->type == Route::JACK_ROUTE)
+ continue;
+ // Amazingly, this single line seems to work.
+ MusEGlobal::audio->msgAddRoute(Route(this, ir->channel, ir->channels), *ir);
+ }
+ }
+ else if(flags & ASSIGN_DEFAULT_ROUTES)
+ {
+ //
+ // add default route to master
+ //
+ OutputList* ol = MusEGlobal::song->outputs();
+ if (!ol->empty()) {
+ AudioOutput* ao = ol->front();
+ switch(type()) {
+ //case Track::MIDI:
+ //case Track::DRUM:
+ //case Track::AUDIO_OUTPUT:
+ // break;
+
+ case Track::WAVE:
+ //case Track::AUDIO_GROUP:
+ case Track::AUDIO_AUX:
+ //case Track::AUDIO_INPUT:
+ //case Track::AUDIO_SOFTSYNTH:
+ MusEGlobal::audio->msgAddRoute(Route(this, -1), Route(ao, -1));
+ //updateFlags |= SC_ROUTE;
+ break;
+ // It should actually never get here now, but just in case.
+ case Track::AUDIO_SOFTSYNTH:
+ MusEGlobal::audio->msgAddRoute(Route(this, 0, channels()), Route(ao, 0, channels()));
+ //updateFlags |= SC_ROUTE;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+}
+
+void AudioTrack::assign(const Track& t, int flags)
+{
+ Track::assign(t, flags);
+ internal_assign(t, flags);
+}
+
AudioTrack::~AudioTrack()
{
delete _efxPipe;
- //for (int i = 0; i < MAX_CHANNELS; ++i)
- // delete[] outBuffers[i];
- //delete[] outBuffers;
-
- // p3.3.15
- //for(int i = 0; i < MAX_CHANNELS; ++i)
- //{
- // if(outBuffers[i])
- // free(outBuffers[i]);
- //}
- // p3.3.38
int chans = _totalOutChannels;
// Number of allocated buffers is always MAX_CHANNELS or more, even if _totalOutChannels is less.
if(chans < MAX_CHANNELS)
chans = MAX_CHANNELS;
- for(int i = 0; i < chans; ++i)
+ if(outBuffers)
{
- if(outBuffers[i])
- free(outBuffers[i]);
+ for(int i = 0; i < chans; ++i)
+ {
+ if(outBuffers[i])
+ free(outBuffers[i]);
+ }
+ delete[] outBuffers;
}
- delete[] outBuffers;
-
- for(iCtrlList i = _controller.begin(); i != _controller.end(); ++i)
- delete i->second;
+ _controller.clearDelete();
}
//---------------------------------------------------------
@@ -1028,8 +1135,7 @@ bool AudioTrack::readProperties(Xml& xml, const QString& tag)
//PluginI* p = 0;
PluginIBase* p = 0;
bool ctlfound = false;
- //int m = l->id() & AC_PLUGIN_CTL_ID_MASK;
- unsigned m = l->id() & AC_PLUGIN_CTL_ID_MASK; // p4.0.21
+ unsigned m = l->id() & AC_PLUGIN_CTL_ID_MASK;
int n = (l->id() >> AC_PLUGIN_CTL_BASE_POW) - 1;
if(n >= 0 && n < PipelineDepth)
{
@@ -1195,8 +1301,7 @@ void AudioTrack::mapRackPluginsToControllers()
// Ignore volume, pan, mute etc.
if(id < AC_PLUGIN_CTL_BASE)
continue;
- //int param = id & AC_PLUGIN_CTL_ID_MASK;
- unsigned param = id & AC_PLUGIN_CTL_ID_MASK; // p4.0.21
+ unsigned param = id & AC_PLUGIN_CTL_ID_MASK;
int idx = (id >> AC_PLUGIN_CTL_BASE_POW) - 1;
//PluginI* p = (*_efxPipe)[idx];
@@ -1346,14 +1451,50 @@ AudioInput::AudioInput()
//setChannels(2);
}
-//AudioInput::AudioInput(const AudioInput& t)
-// : AudioTrack(t)
-AudioInput::AudioInput(const AudioInput& t, bool cloneParts)
- : AudioTrack(t, cloneParts)
- {
- for (int i = 0; i < MAX_CHANNELS; ++i)
- jackPorts[i] = t.jackPorts[i];
- }
+AudioInput::AudioInput(const AudioInput& t, int flags)
+ : AudioTrack(t, flags)
+{
+ for (int i = 0; i < MAX_CHANNELS; ++i)
+ //jackPorts[i] = t.jackPorts[i];
+ jackPorts[i] = 0;
+
+ // Register ports.
+ if(MusEGlobal::checkAudioDevice())
+ {
+ for (int i = 0; i < channels(); ++i)
+ {
+ char buffer[128];
+ snprintf(buffer, 128, "%s-%d", _name.toLatin1().constData(), i);
+ jackPorts[i] = MusEGlobal::audioDevice->registerInPort(buffer, false);
+ }
+ }
+ internal_assign(t, flags);
+}
+
+void AudioInput::assign(const Track& t, int flags)
+{
+ AudioTrack::assign(t, flags);
+ internal_assign(t, flags);
+}
+
+void AudioInput::internal_assign(const Track& t, int flags)
+{
+ if(t.type() != AUDIO_INPUT)
+ return;
+
+ const AudioInput& at = (const AudioInput&)t;
+
+ if(flags & ASSIGN_ROUTES)
+ {
+ for(ciRoute ir = at._inRoutes.begin(); ir != at._inRoutes.end(); ++ir)
+ {
+ // Defer all Jack routes to these copy constructors or assign !
+ if(ir->type != Route::JACK_ROUTE)
+ continue;
+ MusEGlobal::audio->msgAddRoute(*ir, Route(this, ir->channel, ir->channels));
+ }
+ }
+}
//---------------------------------------------------------
// ~AudioInput
@@ -1422,16 +1563,53 @@ AudioOutput::AudioOutput()
//setChannels(2);
}
-//AudioOutput::AudioOutput(const AudioOutput& t)
-// : AudioTrack(t)
-AudioOutput::AudioOutput(const AudioOutput& t, bool cloneParts)
- : AudioTrack(t, cloneParts)
- {
- for (int i = 0; i < MAX_CHANNELS; ++i)
- jackPorts[i] = t.jackPorts[i];
- _nframes = t._nframes;
- }
+AudioOutput::AudioOutput(const AudioOutput& t, int flags)
+ : AudioTrack(t, flags)
+{
+ for (int i = 0; i < MAX_CHANNELS; ++i)
+ //jackPorts[i] = t.jackPorts[i];
+ jackPorts[i] = 0;
+ //_nframes = t._nframes;
+ _nframes = 0;
+
+ // Register ports.
+ if(MusEGlobal::checkAudioDevice())
+ {
+ for (int i = 0; i < channels(); ++i)
+ {
+ char buffer[128];
+ snprintf(buffer, 128, "%s-%d", _name.toLatin1().constData(), i);
+ jackPorts[i] = MusEGlobal::audioDevice->registerOutPort(buffer, false);
+ }
+ }
+ internal_assign(t, flags);
+}
+
+void AudioOutput::assign(const Track& t, int flags)
+{
+ AudioTrack::assign(t, flags);
+ internal_assign(t, flags);
+}
+void AudioOutput::internal_assign(const Track& t, int flags)
+{
+ if(t.type() != AUDIO_OUTPUT)
+ return;
+
+ const AudioOutput& at = (const AudioOutput&)t;
+
+ if(flags & ASSIGN_ROUTES)
+ {
+ for(ciRoute ir = at._outRoutes.begin(); ir != at._outRoutes.end(); ++ir)
+ {
+ // Defer all Jack routes to these copy constructors or assign !
+ if(ir->type != Route::JACK_ROUTE)
+ continue;
+ MusEGlobal::audio->msgAddRoute(Route(this, ir->channel, ir->channels), *ir);
+ }
+ }
+}
+
//---------------------------------------------------------
// ~AudioOutput
//---------------------------------------------------------
@@ -1548,7 +1726,6 @@ AudioAux::AudioAux()
{
//_channels = 0;
//setChannels(2);
- // Changed by Tim. p3.3.15
//for (int i = 0; i < MAX_CHANNELS; ++i)
// buffer[i] = (i < channels()) ? new float[MusEGlobal::segmentSize] : 0;
for(int i = 0; i < MAX_CHANNELS; ++i)
@@ -1560,13 +1737,27 @@ AudioAux::AudioAux()
}
}
+AudioAux::AudioAux(const AudioAux& t, int flags)
+ : AudioTrack(t, flags)
+{
+ //_channels = 0;
+ //setChannels(2);
+ //for (int i = 0; i < MAX_CHANNELS; ++i)
+ // buffer[i] = (i < channels()) ? new float[MusEGlobal::segmentSize] : 0;
+ for(int i = 0; i < MAX_CHANNELS; ++i)
+ {
+ if(i < channels())
+ posix_memalign((void**)(buffer + i), 16, sizeof(float) * MusEGlobal::segmentSize);
+ else
+ buffer[i] = 0;
+ }
+}
//---------------------------------------------------------
// AudioAux
//---------------------------------------------------------
AudioAux::~AudioAux()
{
- // Changed by Tim. p3.3.15
//for (int i = 0; i < channels(); ++i)
// delete[] buffer[i];
for (int i = 0; i < MAX_CHANNELS; ++i) {
@@ -1657,7 +1848,6 @@ void AudioAux::setChannels(int n)
{
if(n > channels())
{
- // Changed by Tim. p3.3.15
//for (int i = channels(); i < n; ++i)
// buffer[i] = new float[MusEGlobal::segmentSize];
for(int i = channels(); i < n; ++i)
@@ -1665,7 +1855,6 @@ void AudioAux::setChannels(int n)
}
else if(n < channels())
{
- // Changed by Tim. p3.3.15
//for (int i = n; i < channels(); ++i)
// delete[] buffer[i];
for(int i = n; i < channels(); ++i)
@@ -1704,7 +1893,6 @@ bool AudioTrack::setRecordFlag1(bool f)
// recording, the _recFile pointer is made into an event,
// then _recFile is made zero before this function is called.
QString s = _recFile->path();
- // Added by Tim. p3.3.8
delete _recFile;
setRecFile(0);