[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Traverso-commit] traverso/src core/Song.cpp core/Song.h core/Tra...
From: |
Remon Sijrier |
Subject: |
[Traverso-commit] traverso/src core/Song.cpp core/Song.h core/Tra... |
Date: |
Mon, 08 Oct 2007 20:46:50 +0000 |
CVSROOT: /sources/traverso
Module name: traverso
Changes by: Remon Sijrier <r_sijrier> 07/10/08 20:46:50
Modified files:
src/core : Song.cpp Song.h Track.cpp Track.h
src/engine : AudioDevice.cpp AudioDevice.h
AudioDeviceThread.cpp
src/traverso : BusMonitor.cpp
src/traverso/dialogs: BusSelectorDialog.cpp
src/traverso/ui: BusSelectorDialog.ui
Log message:
* Added ability to add 'virtual playback buses' in AudioDevice, which
adds one by default, the "Master Out"
* Song now uses the "Master Out" bus provided by audiodevice
* Track no longer gets it's output bus from it's song, but uses the one
set via the BusSelector, which can be any of the playback buses provided by the
audiodevice.
This gives the opportunity to send a Track to another playback bus then
the master out, in case you have a multichannel audiocard
* cleanups in AudioDevice
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/Song.cpp?cvsroot=traverso&r1=1.143&r2=1.144
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/Song.h?cvsroot=traverso&r1=1.68&r2=1.69
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/Track.cpp?cvsroot=traverso&r1=1.66&r2=1.67
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/Track.h?cvsroot=traverso&r1=1.31&r2=1.32
http://cvs.savannah.gnu.org/viewcvs/traverso/src/engine/AudioDevice.cpp?cvsroot=traverso&r1=1.39&r2=1.40
http://cvs.savannah.gnu.org/viewcvs/traverso/src/engine/AudioDevice.h?cvsroot=traverso&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/traverso/src/engine/AudioDeviceThread.cpp?cvsroot=traverso&r1=1.18&r2=1.19
http://cvs.savannah.gnu.org/viewcvs/traverso/src/traverso/BusMonitor.cpp?cvsroot=traverso&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/traverso/src/traverso/dialogs/BusSelectorDialog.cpp?cvsroot=traverso&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/traverso/src/traverso/ui/BusSelectorDialog.ui?cvsroot=traverso&r1=1.2&r2=1.3
Patches:
Index: core/Song.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/Song.cpp,v
retrieving revision 1.143
retrieving revision 1.144
diff -u -b -r1.143 -r1.144
--- core/Song.cpp 28 Sep 2007 18:33:44 -0000 1.143
+++ core/Song.cpp 8 Oct 2007 20:46:48 -0000 1.144
@@ -111,7 +111,6 @@
delete [] gainbuffer;
delete m_diskio;
- delete m_masterOut;
delete m_renderBus;
delete m_hs;
delete m_audiodeviceClient;
@@ -131,7 +130,6 @@
connect(this, SIGNAL(seekStart()), m_diskio, SLOT(seek()),
Qt::QueuedConnection);
connect(this, SIGNAL(prepareRecording()), this,
SLOT(prepare_recording()));
connect(&audiodevice(), SIGNAL(clientRemoved(Client*)), this, SLOT
(audiodevice_client_removed(Client*)));
- connect(&audiodevice(), SIGNAL(started()), this,
SLOT(audiodevice_started()));
connect(&audiodevice(), SIGNAL(driverParamsChanged()), this,
SLOT(audiodevice_params_changed()), Qt::DirectConnection);
connect(m_diskio, SIGNAL(seekFinished()), this, SLOT(seek_finished()),
Qt::QueuedConnection);
connect (m_diskio, SIGNAL(readSourceBufferUnderRun()), this,
SLOT(handle_diskio_readbuffer_underrun()));
@@ -139,8 +137,12 @@
connect(this, SIGNAL(transferStarted()), m_diskio, SLOT(start_io()));
connect(this, SIGNAL(transferStopped()), m_diskio, SLOT(stop_io()));
+ m_playBackBus = 0;
+ m_masterOut = 0;
+ // Not entirely true, but this assigns the playback bus!
+ assign_buses();
+
mixdown = gainbuffer = 0;
- m_masterOut = new AudioBus("Master Out", 2);
m_renderBus = new AudioBus("Render Bus", 2);
resize_buffer(false, audiodevice().get_buffer_size());
m_hs = new QUndoStack(pm().get_undogroup());
@@ -149,8 +151,6 @@
set_context_item( m_acmanager );
- m_playBackBus = audiodevice().get_playback_bus("Playback 1");
-
m_transport = m_stopTransport = m_resumeTransport = m_readyToRecord =
false;
snaplist = new SnapList(this);
workSnap = new Snappable();
@@ -770,10 +770,14 @@
return 0;
}
+ for (int chan=0; chan<m_masterOut->get_channel_count(); ++chan) {
+ Mixer::apply_gain_to_buffer(m_masterOut->get_buffer(chan,
nframes), nframes, get_gain());
+ }
+
// Mix the result into the AudioDevice "physical" buffers
if (m_playBackBus) {
- Mixer::mix_buffers_with_gain(m_playBackBus->get_buffer(0,
nframes), m_masterOut->get_buffer(0, nframes), nframes, get_gain());
- Mixer::mix_buffers_with_gain(m_playBackBus->get_buffer(1,
nframes), m_masterOut->get_buffer(1, nframes), nframes, get_gain());
+ Mixer::mix_buffers_no_gain(m_playBackBus->get_buffer(0,
nframes), m_masterOut->get_buffer(0, nframes), nframes);
+ Mixer::mix_buffers_no_gain(m_playBackBus->get_buffer(1,
nframes), m_masterOut->get_buffer(1, nframes), nframes);
m_pluginChain->process_post_fader(m_masterOut, nframes);
}
@@ -937,8 +941,25 @@
}
}
+void Song::assign_buses()
+{
+ if (m_masterOut) {
+ m_masterOut->set_monitor_peaks(false);
+ }
+ m_playBackBus = audiodevice().get_playback_bus("Playback 1");
+ m_masterOut = audiodevice().get_playback_bus("Master Out");
+ if (m_masterOut) {
+ m_masterOut->set_monitor_peaks(true);
+ }
+ foreach(Track* track, m_tracks) {
+ track->assign_buses();
+ }
+}
+
void Song::audiodevice_params_changed()
{
+ assign_buses();
+
resize_buffer(true, audiodevice().get_buffer_size());
// The samplerate possibly has been changed, this initiates
@@ -1021,11 +1042,6 @@
}
}
-void Song::audiodevice_started( )
-{
- m_playBackBus = audiodevice().get_playback_bus("Playback 1");
-}
-
const TimeRef& Song::get_last_location() const
{
return m_acmanager->get_last_location();
@@ -1334,4 +1350,3 @@
}
-// eof
Index: core/Song.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/Song.h,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -b -r1.68 -r1.69
--- core/Song.h 11 Sep 2007 18:37:30 -0000 1.68
+++ core/Song.h 8 Oct 2007 20:46:48 -0000 1.69
@@ -209,6 +209,7 @@
void start_seek();
void start_transport_rolling(bool realtime);
void stop_transport_rolling();
+ void assign_buses();
void resize_buffer(bool updateArmStatus, nframes_t size);
@@ -219,7 +220,6 @@
public slots :
void seek_finished();
void audiodevice_client_removed(Client* );
- void audiodevice_started();
void audiodevice_params_changed();
void set_gain(float gain);
Index: core/Track.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/Track.cpp,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -b -r1.66 -r1.67
--- core/Track.cpp 28 Sep 2007 18:33:44 -0000 1.66
+++ core/Track.cpp 8 Oct 2007 20:46:49 -0000 1.67
@@ -52,10 +52,11 @@
m_sortIndex = -1;
m_id = create_id();
- busIn = "Capture 1";
- busOut = "MasterOut";
-
init();
+
+ m_busInName = "Capture 1";
+ m_busOutName = "Master Out";
+ set_bus_out(m_busOutName);
}
Track::Track( Song * song, const QDomNode node)
@@ -80,7 +81,8 @@
m_pluginChain = new PluginChain(this, m_song);
m_fader = m_pluginChain->get_fader();
m_fader->set_gain(1.0);
- m_captureRightChannel = m_captureLeftChannel = true;
+ m_captureRightChannel = m_captureLeftChannel = m_playbackRightChannel =
m_playbackLeftChannel = true;
+ m_outBus = 0;
}
QDomNode Track::get_state( QDomDocument doc, bool istemplate)
@@ -97,10 +99,12 @@
node.setAttribute("height", m_height);
node.setAttribute("sortindex", m_sortIndex);
node.setAttribute("numtakes", numtakes);
- node.setAttribute("InBus", busIn.data());
- node.setAttribute("OutBus", busOut.data());
+ node.setAttribute("InBus", m_busInName.data());
+ node.setAttribute("OutBus", m_busOutName.data());
node.setAttribute("CaptureLeftChannel", m_captureLeftChannel);
node.setAttribute("CaptureRightChannel", m_captureRightChannel);
+ node.setAttribute("PlaybackLeftChannel", m_playbackLeftChannel);
+ node.setAttribute("PlaybackRightChannel", m_playbackRightChannel);
if (! istemplate ) {
QDomNode clips = doc.createElement("Clips");
@@ -149,10 +153,17 @@
numtakes = e.attribute( "numtakes", "").toInt();
m_captureRightChannel = e.attribute("CaptureRightChannel", "1").toInt();
m_captureLeftChannel = e.attribute("CaptureLeftChannel", "1").toInt();
+ m_playbackRightChannel = e.attribute("PlaybackRightChannel",
"1").toInt();
+ m_playbackLeftChannel = e.attribute("PlaybackLeftChannel",
"1").toInt();
+
// never ever allow both to be 0 at the same time!
if ( ! (m_captureRightChannel || m_captureLeftChannel) ) {
m_captureRightChannel = m_captureLeftChannel = 1;
}
+ // never ever allow both to be 0 at the same time!
+ if ( ! (m_playbackRightChannel || m_playbackLeftChannel) ) {
+ m_playbackRightChannel = m_playbackLeftChannel = 1;
+ }
QDomElement ClipsNode = node.firstChildElement("Clips");
if (!ClipsNode.isNull()) {
@@ -242,7 +253,7 @@
{
PENTER;
set_armed(true);
- AudioBus* bus = audiodevice().get_capture_bus(busIn);
+ AudioBus* bus = audiodevice().get_capture_bus(m_busInName);
if (bus) {
bus->set_monitor_peaks(true);
}
@@ -254,7 +265,7 @@
{
PENTER;
set_armed(false);
- AudioBus* bus = audiodevice().get_capture_bus(busIn);
+ AudioBus* bus = audiodevice().get_capture_bus(m_busInName);
if (bus) {
bus->set_monitor_peaks(false);
}
@@ -266,7 +277,7 @@
bool wasArmed=isArmed;
if (isArmed)
disarm();
- busIn=bus;
+ m_busInName=bus;
if (wasArmed) {
arm();
}
@@ -276,10 +287,39 @@
void Track::set_bus_out(QByteArray bus)
{
- busOut=bus;
+ PENTER;
+ AudioBus* newbus = audiodevice().get_playback_bus(bus);
+ if (newbus) {
+ newbus->set_monitor_peaks(true);
+ } else {
+ info().warning(tr("Track: Cannot assign OutBus to %1, it does
not exist!").arg(bus.data()));
+ }
+
+ if (m_outBus) {
+ m_outBus->set_monitor_peaks(false);
+ }
+
+ m_busOutName=bus;
+
+ if (m_song->is_transport_rolling()) {
+ THREAD_SAVE_INVOKE(this, newbus,
private_assign_out_bus(AudioBus*));
+ } else {
+ private_assign_out_bus(newbus);
+ }
+
emit outBusChanged();
}
+void Track::private_assign_out_bus(AudioBus* bus)
+{
+ PENTER;
+ m_outBus = bus;
+ // fallback to master out if bus does not exist!
+ if (!m_outBus) {
+ m_outBus = m_song->get_master_out();
+ }
+}
+
bool Track::is_solo()
{
return isSolo;
@@ -320,7 +360,7 @@
clip->set_track(this);
clip->set_track_start_location(m_song->get_transport_location());
- if (clip->init_recording(busIn) < 0) {
+ if (clip->init_recording(m_busInName) < 0) {
PERROR("Could not create AudioClip to record to!");
resources_manager()->destroy_clip(clip);
return 0;
@@ -458,7 +498,7 @@
processResult |= m_pluginChain->process_post_fader(bus, nframes);
for (int i=0; i<bus->get_channel_count(); ++i) {
-
Mixer::mix_buffers_no_gain(m_song->get_master_out()->get_buffer(i, nframes),
bus->get_buffer(i, nframes), nframes);
+ Mixer::mix_buffers_no_gain(m_outBus->get_buffer(i, nframes),
bus->get_buffer(i, nframes), nframes);
}
return processResult;
@@ -566,5 +606,19 @@
emit inBusChanged();
}
-// eof
+void Track::set_playback_right_channel(bool play)
+{
+ m_playbackRightChannel = play;
+ emit outBusChanged();
+}
+
+void Track::set_playback_left_channel(bool play)
+{
+ m_playbackLeftChannel = play;
+ emit outBusChanged();
+}
+void Track::assign_buses( )
+{
+ set_bus_out(m_busOutName);
+}
Index: core/Track.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/Track.h,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -b -r1.31 -r1.32
--- core/Track.h 10 Sep 2007 18:42:49 -0000 1.31
+++ core/Track.h 8 Oct 2007 20:46:49 -0000 1.32
@@ -38,6 +38,7 @@
class Song;
class PluginChain;
class Plugin;
+class AudioBus;
class Track : public ContextItem
{
@@ -69,8 +70,8 @@
AudioClip* get_clip_after(const TimeRef& pos);
AudioClip* get_clip_before(const TimeRef& pos);
void get_render_range(TimeRef& startlocation, TimeRef& endlocation);
- QString get_bus_in() const {return busIn;}
- QString get_bus_out() const{return busOut;}
+ QString get_bus_in() const {return m_busInName;}
+ QString get_bus_out() const{return m_busOutName;}
int get_height() const {return m_height;}
float get_pan() const {return m_pan;}
Song* get_song() const {return m_song;}
@@ -94,6 +95,8 @@
void set_height(int h);
void set_capture_left_channel(bool capture);
void set_capture_right_channel(bool capture);
+ void set_playback_right_channel(bool play);
+ void set_playback_left_channel(bool play);
int set_state( const QDomNode& node );
@@ -102,29 +105,27 @@
bool is_muted_by_solo();
bool is_solo();
bool armed();
- bool capture_left_channel()
- {
- return m_captureLeftChannel;
- }
- bool capture_right_channel()
- {
- return m_captureRightChannel;
- }
+ bool capture_left_channel() {return m_captureLeftChannel;}
+ bool capture_right_channel() {return m_captureRightChannel;}
+ bool playback_left_channel() {return m_playbackLeftChannel;}
+ bool playback_right_channel() {return m_playbackRightChannel;}
// End bool functions
int process(nframes_t nframes);
+ void assign_buses();
private :
Song* m_song;
AudioClipList audioClipList;
PluginChain* m_pluginChain;
+ AudioBus* m_outBus;
GainEnvelope* m_fader;
float m_pan;
int numtakes;
- QByteArray busIn;
- QByteArray busOut;
+ QByteArray m_busInName;
+ QByteArray m_busOutName;
QString m_name;
@@ -137,6 +138,8 @@
bool mutedBySolo;
bool m_captureLeftChannel;
bool m_captureRightChannel;
+ bool m_playbackRightChannel;
+ bool m_playbackLeftChannel;
void set_armed(bool armed);
void init();
@@ -169,6 +172,7 @@
private slots:
void private_add_clip(AudioClip* clip);
void private_remove_clip(AudioClip* clip);
+ void private_assign_out_bus(AudioBus* bus);
};
Index: engine/AudioDevice.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/engine/AudioDevice.cpp,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -b -r1.39 -r1.40
--- engine/AudioDevice.cpp 6 Oct 2007 14:17:59 -0000 1.39
+++ engine/AudioDevice.cpp 8 Oct 2007 20:46:49 -0000 1.40
@@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-$Id: AudioDevice.cpp,v 1.39 2007/10/06 14:17:59 r_sijrier Exp $
+$Id: AudioDevice.cpp,v 1.40 2007/10/08 20:46:49 r_sijrier Exp $
*/
#include "AudioDevice.h"
@@ -117,7 +117,7 @@
AudioBus* playbackBus =
audiodevice().get_playback_bus("Playback 1");
// Just copy the captured audio to the playback buses.
- for (int i=0; i<captureBuses->get_channel_count(); ++i) {
+ for (int i=0; i<m_captureBuses->get_channel_count(); ++i) {
memcpy(captureBus->get_channel(i)->get_buffer(nframes),
playbackBus->get_channel(i)->get_buffer(nframes), nframes);
}
@@ -141,8 +141,8 @@
AudioDevice::AudioDevice()
{
m_runAudioThread = false;
- driver = 0;
- audioThread = 0;
+ m_driver = 0;
+ m_audioThread = 0;
m_bufferSize = 1024;
m_xrunCount = 0;
m_cpuTime = new RingBufferNPT<trav_time_t>(4096);
@@ -151,19 +151,19 @@
#if defined (JACK_SUPPORT)
if (libjack_is_present) {
- availableDrivers << "Jack";
+ m_availableDrivers << "Jack";
}
#endif
#if defined (ALSA_SUPPORT)
- availableDrivers << "ALSA";
+ m_availableDrivers << "ALSA";
#endif
#if defined (PORTAUDIO_SUPPORT)
- availableDrivers << "PortAudio";
+ m_availableDrivers << "PortAudio";
#endif
- availableDrivers << "Null Driver";
+ m_availableDrivers << "Null Driver";
// tsar is a singleton, so initialization is done on first tsar() call
// Tsar makes use of a QTimer to cleanup the processed events.
@@ -185,8 +185,8 @@
shutdown();
- if (audioThread) {
- delete audioThread;
+ if (m_audioThread) {
+ delete m_audioThread;
}
delete m_cpuTime;
@@ -196,18 +196,18 @@
void AudioDevice::free_memory()
{
- foreach(AudioBus* bus, captureBuses) {
+ foreach(AudioBus* bus, m_captureBuses) {
delete bus;
}
- foreach(AudioBus* bus, playbackBuses) {
+ foreach(AudioBus* bus, m_playbackBuses) {
delete bus;
}
- captureChannels.clear();
- playbackChannels.clear();
- captureBuses.clear();
- playbackBuses.clear();
+ m_captureChannels.clear();
+ m_playbackChannels.clear();
+ m_captureBuses.clear();
+ m_playbackBuses.clear();
}
/**
@@ -260,18 +260,18 @@
int AudioDevice::run_one_cycle( nframes_t nframes, float )
{
- if (driver->read(nframes) < 0) {
+ if (m_driver->read(nframes) < 0) {
qDebug("driver read failed!");
return -1;
}
- for (int i=0; i<clients.size(); ++i) {
- if (clients.at(i)->process(nframes) < 0) {
+ for (int i=0; i<m_clients.size(); ++i) {
+ if (m_clients.at(i)->process(nframes) < 0) {
// ?
}
}
- if (driver->write(nframes) < 0) {
+ if (m_driver->write(nframes) < 0) {
qDebug("driver write failed!");
return -1;
}
@@ -280,6 +280,16 @@
return 0;
}
+void AudioDevice::post_process( )
+{
+ foreach(AudioBus* bus, m_virtualPlaybackBuses) {
+ if (bus->is_monitoring_peaks()) {
+ bus->monitor_peaks();
+ }
+ }
+ tsar().process_events();
+}
+
void AudioDevice::delay( float )
{
}
@@ -290,7 +300,7 @@
*/
uint AudioDevice::capture_buses_count( ) const
{
- return captureChannels.size();
+ return m_captureChannels.size();
}
/**
@@ -299,11 +309,11 @@
*/
uint AudioDevice::playback_buses_count( ) const
{
- return playbackChannels.size();
+ return m_playbackChannels.size();
}
/**
- * This function is used to initialize the AudioDevice's audioThread with the
supplied
+ * This function is used to initialize the AudioDevice's m_audioThread with
the supplied
* rate, bufferSize and driver type. In case the AudioDevice allready was
configured,
* it will stop the AudioDeviceThread and emits the stopped() signal,
* re-inits the AlsaDriver with the new paramaters, when succesfull emits the
driverParamsChanged() signal,
@@ -333,12 +343,17 @@
return;
}
- driver->attach();
+ m_driver->attach();
setup_buses();
emit driverParamsChanged();
+ // It could be possible that one of our clients used Tsar to get/set
AudioBuses
+ // after the driverParamsChanged() signal, so we have to process those
events first
+ // before restarting!
+ tsar().process_events();
+
m_runAudioThread = 1;
if ((driverType == "ALSA") || (driverType == "Null Driver")) {
@@ -346,25 +361,25 @@
printf("Starting AudioDeviceThread..... ");
- if (!audioThread) {
- audioThread = new AudioDeviceThread(this);
+ if (!m_audioThread) {
+ m_audioThread = new AudioDeviceThread(this);
}
// m_cycleStartTime/EndTime are set before/after the first
cycle.
- // to avoid a "100%" cpu usage value during audioThread
startup, set the
+ // to avoid a "100%" cpu usage value during m_audioThread
startup, set the
// m_cycleStartTime here!
m_cycleStartTime = get_microseconds();
// When the audiothread fails for some reason we catch it in
audiothread_finished()
// by connecting the finished signal of the audio thread!
- connect(audioThread, SIGNAL(finished()), this,
SLOT(audiothread_finished()));
+ connect(m_audioThread, SIGNAL(finished()), this,
SLOT(audiothread_finished()));
// Start the audio thread, the driver->start() will be called
from there!!
- audioThread->start();
+ m_audioThread->start();
// It appears this check is a little silly because it always
returns true
// this close after calling the QThread::start() function :-(
- if (audioThread->isRunning()) {
+ if (m_audioThread->isRunning()) {
printf("Running!\n");
}
}
@@ -374,19 +389,19 @@
if (libjack_is_present) {
if (driverType == "Jack") {
- if (driver->start() == -1) {
+ if (m_driver->start() == -1) {
// jack driver failed to start, fallback to
Null Driver:
set_parameters(rate, bufferSize, "Null Driver");
}
- connect(&jackShutDownChecker, SIGNAL(timeout()), this,
SLOT(check_jack_shutdown()));
- jackShutDownChecker.start(500);
+ connect(&m_jackShutDownChecker, SIGNAL(timeout()),
this, SLOT(check_jack_shutdown()));
+ m_jackShutDownChecker.start(500);
}
}
#endif
if (driverType == "PortAudio") {
- if (driver->start() == -1) {
+ if (m_driver->start() == -1) {
// PortAudio driver failed to start, fallback to Null
Driver:
set_parameters(rate, bufferSize, "Null Driver");
}
@@ -401,11 +416,11 @@
#if defined (JACK_SUPPORT)
if (libjack_is_present) {
if (driverType == "Jack") {
- driver = new JackDriver(this, m_rate, m_bufferSize);
- if (driver->setup(capture, playback) < 0) {
+ m_driver = new JackDriver(this, m_rate, m_bufferSize);
+ if (m_driver->setup(capture, playback) < 0) {
info().warning(tr("Audiodevice: Failed to
create the Jack Driver"));
- delete driver;
- driver = 0;
+ delete m_driver;
+ m_driver = 0;
return -1;
}
m_driverType = driverType;
@@ -416,11 +431,11 @@
#if defined (ALSA_SUPPORT)
if (driverType == "ALSA") {
- driver = new AlsaDriver(this, m_rate, m_bufferSize);
- if (driver->setup(capture,playback, cardDevice) < 0) {
+ m_driver = new AlsaDriver(this, m_rate, m_bufferSize);
+ if (m_driver->setup(capture,playback, cardDevice) < 0) {
info().warning(tr("Audiodevice: Failed to create the
ALSA Driver"));
- delete driver;
- driver = 0;
+ delete m_driver;
+ m_driver = 0;
return -1;
}
m_driverType = driverType;
@@ -430,11 +445,11 @@
#if defined (PORTAUDIO_SUPPORT)
if (driverType == "PortAudio") {
- driver = new PADriver(this, m_rate, m_bufferSize);
- if (driver->setup(capture, playback, cardDevice) < 0) {
+ m_driver = new PADriver(this, m_rate, m_bufferSize);
+ if (m_driver->setup(capture, playback, cardDevice) < 0) {
info().warning(tr("Audiodevice: Failed to create the
PortAudio Driver"));
- delete driver;
- driver = 0;
+ delete m_driver;
+ m_driver = 0;
return -1;
}
m_driverType = driverType;
@@ -444,7 +459,7 @@
if (driverType == "Null Driver") {
printf("Creating Null Driver...\n");
- driver = new Driver(this, m_rate, m_bufferSize);
+ m_driver = new Driver(this, m_rate, m_bufferSize);
m_driverType = driverType;
return 1;
}
@@ -456,14 +471,14 @@
AudioChannel* AudioDevice::register_capture_channel(const QByteArray&
chanName, const QString& audioType, int flags, uint , uint channel )
{
AudioChannel* chan = new AudioChannel(chanName, audioType, flags,
channel);
- captureChannels.insert(chanName, chan);
+ m_captureChannels.insert(chanName, chan);
return chan;
}
AudioChannel* AudioDevice::register_playback_channel(const QByteArray&
chanName, const QString& audioType, int flags, uint , uint channel )
{
AudioChannel* chan = new AudioChannel(chanName, audioType, flags,
channel);
- playbackChannels.insert(chanName, chan);
+ m_playbackChannels.insert(chanName, chan);
return chan;
}
@@ -487,23 +502,23 @@
m_runAudioThread = 0;
- if (audioThread) {
- disconnect(audioThread, SIGNAL(finished()), this,
SLOT(audiothread_finished()));
+ if (m_audioThread) {
+ disconnect(m_audioThread, SIGNAL(finished()), this,
SLOT(audiothread_finished()));
- // Wait until the audioThread has finished execution. One second
+ // Wait until the m_audioThread has finished execution. One
second
// should do, if it's still running then, the thread must have
gone wild or something....
- if (audioThread->isRunning()) {
+ if (m_audioThread->isRunning()) {
printf("Starting to shutdown AudioThread..\n");
- r = audioThread->wait(1000);
+ r = m_audioThread->wait(1000);
printf("AudioDeviceThread finished, stopping driver\n");
}
}
- if (driver) {
- driver->stop();
- delete driver;
- driver = 0;
+ if (m_driver) {
+ m_driver->stop();
+ delete m_driver;
+ m_driver = 0;
}
free_memory();
@@ -521,9 +536,10 @@
QStringList AudioDevice::get_capture_buses_names( ) const
{
QStringList names;
- foreach(AudioBus* bus, captureBuses) {
+ foreach(AudioBus* bus, m_captureBuses) {
names.append(bus->get_name());
}
+ names.sort();
return names;
}
@@ -537,9 +553,13 @@
QStringList AudioDevice::get_playback_buses_names( ) const
{
QStringList names;
- foreach(AudioBus* bus, playbackBuses) {
+ foreach(AudioBus* bus, m_playbackBuses) {
+ names.append(bus->get_name());
+ }
+ foreach(AudioBus* bus, m_virtualPlaybackBuses) {
names.append(bus->get_name());
}
+ names.sort();
return names;
}
@@ -548,25 +568,33 @@
int number = 1;
QByteArray name;
- for (int i=1; i <= captureChannels.size();) {
+ for (int i=1; i <= m_captureChannels.size();) {
name = "Capture " + QByteArray::number(number++);
AudioBus* bus = new AudioBus(name);
-
bus->add_channel(captureChannels.value("capture_"+QByteArray::number(i++)));
-
bus->add_channel(captureChannels.value("capture_"+QByteArray::number(i++)));
- captureBuses.insert(name, bus);
+
bus->add_channel(m_captureChannels.value("capture_"+QByteArray::number(i++)));
+
bus->add_channel(m_captureChannels.value("capture_"+QByteArray::number(i++)));
+ m_captureBuses.insert(name, bus);
}
-// PWARN("Capture buses count is: %d", captureBuses.size());
+// PWARN("Capture buses count is: %d", m_captureBuses.size());
number = 1;
- for (int i=1; i <= playbackChannels.size();) {
+ for (int i=1; i <= m_playbackChannels.size();) {
name = "Playback " + QByteArray::number(number++);
AudioBus* bus = new AudioBus(name);
-
bus->add_channel(playbackChannels.value("playback_"+QByteArray::number(i++)));
-
bus->add_channel(playbackChannels.value("playback_"+QByteArray::number(i++)));
- playbackBuses.insert(name, bus);
+
bus->add_channel(m_playbackChannels.value("playback_"+QByteArray::number(i++)));
+
bus->add_channel(m_playbackChannels.value("playback_"+QByteArray::number(i++)));
+ m_playbackBuses.insert(name, bus);
+ }
+
+ // This virtual bus is highly likely used all the time, so we create it
beforehand
+ create_virtual_playback_bus("Master Out", 2);
+
+ foreach(AudioBus* bus, m_virtualPlaybackBuses) {
+ bus->set_buffer_size(m_bufferSize);
}
-// PWARN("Playback buses count is: %d", playbackBuses.size());
+
+// PWARN("Playback buses count is: %d", m_playbackBuses.size());
}
/**
@@ -594,8 +622,8 @@
*/
QString AudioDevice::get_device_name( ) const
{
- if (driver)
- return driver->get_device_name();
+ if (m_driver)
+ return m_driver->get_device_name();
return tr("No Device Configured");
}
@@ -605,8 +633,8 @@
*/
QString AudioDevice::get_device_longname( ) const
{
- if (driver)
- return driver->get_device_longname();
+ if (m_driver)
+ return m_driver->get_device_longname();
return tr("No Device Configured");
}
@@ -616,7 +644,7 @@
*/
QStringList AudioDevice::get_available_drivers( ) const
{
- return availableDrivers;
+ return m_availableDrivers;
}
/**
@@ -636,13 +664,13 @@
{
#if defined (JACK_SUPPORT)
if (libjack_is_present)
- if (driver && m_driverType == "Jack")
- return ((JackDriver*)driver)->get_cpu_load();
+ if (m_driver && m_driverType == "Jack")
+ return ((JackDriver*)m_driver)->get_cpu_load();
#endif
#if defined (PORTAUDIO_SUPPORT)
- if (driver && m_driverType == "PortAudio")
- return ((PADriver*)driver)->get_cpu_load();
+ if (m_driver && m_driverType == "PortAudio")
+ return ((PADriver*)m_driver)->get_cpu_load();
#endif
@@ -663,23 +691,18 @@
return result;
}
-void AudioDevice::post_process( )
-{
- tsar().process_events();
-}
-
void AudioDevice::private_add_client(Client* client)
{
// printf("Adding client %s\n", client->m_name.toAscii().data());
- clients.append(client);
+ m_clients.append(client);
}
void AudioDevice::private_remove_client(Client* client)
{
- int index = clients.indexOf(client);
+ int index = m_clients.indexOf(client);
if (index >= 0) {
- clients.removeAt( index );
+ m_clients.removeAt( index );
}
// printf("Removing client %s\n", client->m_name.toAscii().data());
@@ -708,7 +731,7 @@
void AudioDevice::mili_sleep(int msec)
{
- audioThread->mili_sleep(msec);
+ m_audioThread->mili_sleep(msec);
}
@@ -737,14 +760,14 @@
void AudioDevice::check_jack_shutdown()
{
if (libjack_is_present) {
- JackDriver* jackdriver = qobject_cast<JackDriver*>(driver);
+ JackDriver* jackdriver = qobject_cast<JackDriver*>(m_driver);
if (jackdriver) {
if ( ! jackdriver->is_jack_running()) {
- jackShutDownChecker.stop();
+ m_jackShutDownChecker.stop();
printf("jack shutdown detected\n");
info().critical(tr("The Jack server has been
shutdown!"));
- delete driver;
- driver = 0;
+ delete m_driver;
+ m_driver = 0;
set_parameters(44100, m_bufferSize, "Null
Driver");
}
}
@@ -769,8 +792,8 @@
#endif
int result = 0;
- for (int i=0; i<clients.size(); ++i) {
- result = clients.at(i)->transport_control(state);
+ for (int i=0; i<m_clients.size(); ++i) {
+ result = m_clients.at(i)->transport_control(state);
}
return result;
}
@@ -842,7 +865,7 @@
JackDriver* AudioDevice::slaved_jack_driver()
{
if (libjack_is_present) {
- JackDriver* jackdriver = qobject_cast<JackDriver*>(driver);
+ JackDriver* jackdriver = qobject_cast<JackDriver*>(m_driver);
if (jackdriver && jackdriver->is_slave()) {
return jackdriver;
}
@@ -852,5 +875,23 @@
}
#endif
-//eof
+AudioBus* AudioDevice::create_virtual_playback_bus(QByteArray name, int
channelcount)
+{
+ AudioBus* bus = m_virtualPlaybackBuses.value(name);
+
+ if (! bus) {
+ bus = new AudioBus(name, channelcount);
+ bus->set_buffer_size(m_bufferSize);
+ m_virtualPlaybackBuses.insert(name, bus);
+ }
+
+ return bus;
+}
+
+AudioBus * AudioDevice::get_playback_bus(QByteArray name) const
+{
+ AudioBus* bus = m_playbackBuses.value(name);
+ if (!bus) bus = m_virtualPlaybackBuses.value(name);
+ return bus;
+}
Index: engine/AudioDevice.h
===================================================================
RCS file: /sources/traverso/traverso/src/engine/AudioDevice.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- engine/AudioDevice.h 19 Jul 2007 12:28:42 -0000 1.20
+++ engine/AudioDevice.h 8 Oct 2007 20:46:49 -0000 1.21
@@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-$Id: AudioDevice.h,v 1.20 2007/07/19 12:28:42 r_sijrier Exp $
+$Id: AudioDevice.h,v 1.21 2007/10/08 20:46:49 r_sijrier Exp $
*/
#ifndef AUDIODEVICE_H
@@ -71,10 +71,7 @@
* @param name The name of the Playback Bus
* @return An AudioBus if one exists with name \a name, 0 on failure
*/
- AudioBus* get_playback_bus(QByteArray name) const
- {
- return playbackBuses.value(name);
- }
+ AudioBus* get_playback_bus(QByteArray name) const;
/**
* Get the Capture AudioBus instance with name \a name.
@@ -86,11 +83,12 @@
* @param name The name of the Capture Bus
* @return An AudioBus if one exists with name \a name, 0 on failure
*/
- AudioBus* get_capture_bus(QByteArray name) const
- {
- return captureBuses.value(name);
+ AudioBus* get_capture_bus(QByteArray name) const {
+ return m_captureBuses.value(name);
}
+ AudioBus* create_virtual_playback_bus(QByteArray name, int
channelcount);
+
QStringList get_capture_buses_names() const;
QStringList get_playback_buses_names() const;
@@ -139,17 +137,19 @@
friend class AudioDeviceThread;
- Driver* driver;
- AudioDeviceThread* audioThread;
- QList<Client *> clients;
- QHash<QByteArray, AudioChannel* > playbackChannels;
- QHash<QByteArray, AudioChannel* > captureChannels;
- QHash<QByteArray, AudioBus* > playbackBuses;
- QHash<QByteArray, AudioBus* > captureBuses;
- QStringList availableDrivers;
+ Driver* m_driver;
+ AudioDeviceThread* m_audioThread;
+ QList<Client *> m_clients;
+ QHash<QByteArray, AudioChannel* > m_playbackChannels;
+ QHash<QByteArray, AudioChannel* > m_captureChannels;
+ QHash<QByteArray, AudioBus* > m_playbackBuses;
+ QHash<QByteArray, AudioBus* > m_captureBuses;
+ QHash<QByteArray, AudioBus* > m_virtualPlaybackBuses;
+ QStringList m_availableDrivers;
QTimer m_xrunResetTimer;
+
#if defined (JACK_SUPPORT)
- QTimer jackShutDownChecker;
+ QTimer m_jackShutDownChecker;
JackDriver* slaved_jack_driver();
friend class JackDriver;
#endif
@@ -196,7 +196,7 @@
Driver* get_driver() const
{
- return driver;
+ return m_driver;
}
void mili_sleep(int msec);
Index: engine/AudioDeviceThread.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/engine/AudioDeviceThread.cpp,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -b -r1.18 -r1.19
--- engine/AudioDeviceThread.cpp 8 May 2007 16:44:31 -0000 1.18
+++ engine/AudioDeviceThread.cpp 8 Oct 2007 20:46:49 -0000 1.19
@@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-$Id: AudioDeviceThread.cpp,v 1.18 2007/05/08 16:44:31 r_sijrier Exp $
+$Id: AudioDeviceThread.cpp,v 1.19 2007/10/08 20:46:49 r_sijrier Exp $
*/
#include "AudioDeviceThread.h"
@@ -101,7 +101,7 @@
become_realtime(m_realTime);
- if (m_device->driver->start() < 0) {
+ if (m_device->m_driver->start() < 0) {
watchdog.terminate();
watchdog.wait();
return;
Index: traverso/BusMonitor.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/traverso/BusMonitor.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- traverso/BusMonitor.cpp 10 May 2007 20:02:36 -0000 1.11
+++ traverso/BusMonitor.cpp 8 Oct 2007 20:46:49 -0000 1.12
@@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-$Id: BusMonitor.cpp,v 1.11 2007/05/10 20:02:36 r_sijrier Exp $
+$Id: BusMonitor.cpp,v 1.12 2007/10/08 20:46:49 r_sijrier Exp $
*/
#include <libtraverso.h>
@@ -106,12 +106,17 @@
meter->hide();
}
+ list.clear();
list = audiodevice().get_playback_buses_names();
- if (list.size())
+ foreach(QString name, list)
{
- VUMeter* meter = new VUMeter( this,
audiodevice().get_playback_bus(list.at(0).toAscii()) );
+ AudioBus* bus = audiodevice().get_playback_bus(name.toAscii());
+ VUMeter* meter = new VUMeter( this, bus);
+ connect(bus, SIGNAL(monitoringPeaksStarted()), meter,
SLOT(peak_monitoring_started()));
+ connect(bus, SIGNAL(monitoringPeaksStopped()), meter,
SLOT(peak_monitoring_stopped()));
layout->addWidget(meter);
outMeters.append(meter);
+ meter->hide();
}
layout->addSpacing(4);
Index: traverso/dialogs/BusSelectorDialog.cpp
===================================================================
RCS file:
/sources/traverso/traverso/src/traverso/dialogs/BusSelectorDialog.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- traverso/dialogs/BusSelectorDialog.cpp 25 May 2007 04:13:11 -0000
1.3
+++ traverso/dialogs/BusSelectorDialog.cpp 8 Oct 2007 20:46:49 -0000
1.4
@@ -55,6 +55,15 @@
QListWidgetItem* item = new QListWidgetItem(busesListWidget);
item->setText(name);
}
+
+ busesListWidgetPlayback->clear();
+ names.clear();
+ names << audiodevice().get_playback_buses_names();
+
+ foreach(QString name, names) {
+ QListWidgetItem* item = new
QListWidgetItem(busesListWidgetPlayback);
+ item->setText(name);
+ }
}
void BusSelectorDialog::current_track_changed(int index)
@@ -75,10 +84,7 @@
QList<QListWidgetItem *> list =
busesListWidget->findItems(m_currentTrack->get_bus_in(), Qt::MatchExactly);
- if (!list.size()) {
- return;
- }
-
+ if (list.size()) {
QListWidgetItem* item = list.at(0);
item->setSelected(true);
@@ -89,6 +95,28 @@
} else {
radioRightOnly->setChecked(true);
}
+ }
+
+
+ selectedlist = busesListWidgetPlayback->selectedItems();
+
+ if (selectedlist.size()) {
+ selectedlist.at(0)->setSelected(false);
+ }
+
+ list =
busesListWidgetPlayback->findItems(m_currentTrack->get_bus_out(),
Qt::MatchExactly);
+
+ if (list.size()) {
+ QListWidgetItem* item = list.at(0);
+ item->setSelected(true);
+ if (m_currentTrack->playback_left_channel() &&
m_currentTrack->playback_right_channel()) {
+ radioBothPlayback->setChecked(true);
+ } else if (m_currentTrack->playback_left_channel()) {
+ radioLeftOnlyPlayback->setChecked(true);
+ } else {
+ radioRightOnlyPlayback->setChecked(true);
+ }
+ }
}
@@ -114,6 +142,23 @@
}
}
+ list = busesListWidgetPlayback->selectedItems();
+
+ if (list.size()) {
+ m_currentTrack->set_bus_out(list.at(0)->text().toAscii());
+
+ if (radioBothPlayback->isChecked()) {
+ m_currentTrack->set_playback_left_channel(true);
+ m_currentTrack->set_playback_right_channel(true);
+ } else if (radioLeftOnlyPlayback->isChecked()) {
+ m_currentTrack->set_playback_left_channel(true);
+ m_currentTrack->set_playback_right_channel(false);
+ } else {
+ m_currentTrack->set_playback_left_channel(false);
+ m_currentTrack->set_playback_right_channel(true);
+ }
+ }
+
hide();
}
Index: traverso/ui/BusSelectorDialog.ui
===================================================================
RCS file: /sources/traverso/traverso/src/traverso/ui/BusSelectorDialog.ui,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- traverso/ui/BusSelectorDialog.ui 5 Apr 2007 13:15:07 -0000 1.2
+++ traverso/ui/BusSelectorDialog.ui 8 Oct 2007 20:46:49 -0000 1.3
@@ -5,34 +5,35 @@
<rect>
<x>0</x>
<y>0</y>
- <width>185</width>
- <height>202</height>
+ <width>321</width>
+ <height>402</height>
</rect>
</property>
<property name="windowTitle" >
<string>Bus Selector</string>
</property>
<layout class="QVBoxLayout" >
- <property name="margin" >
- <number>9</number>
- </property>
+ <item>
+ <layout class="QHBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
- <item>
- <layout class="QHBoxLayout" >
- <property name="margin" >
+ <property name="leftMargin" >
<number>0</number>
</property>
- <property name="spacing" >
- <number>6</number>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
</property>
<item>
<widget class="QLabel" name="label_3" >
<property name="sizePolicy" >
- <sizepolicy>
- <hsizetype>5</hsizetype>
- <vsizetype>5</vsizetype>
+ <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
<horstretch>2</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -45,9 +46,7 @@
<item>
<widget class="QComboBox" name="trackComboBox" >
<property name="sizePolicy" >
- <sizepolicy>
- <hsizetype>5</hsizetype>
- <vsizetype>0</vsizetype>
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
<horstretch>5</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -57,50 +56,115 @@
</layout>
</item>
<item>
+ <widget class="QGroupBox" name="groupBox_2" >
+ <property name="title" >
+ <string>Capture Buses</string>
+ </property>
<layout class="QHBoxLayout" >
- <property name="margin" >
+ <item>
+ <widget class="QListWidget" name="busesListWidget" />
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
<number>0</number>
</property>
- <property name="spacing" >
- <number>9</number>
+ <property name="topMargin" >
+ <number>0</number>
</property>
- <item>
- <layout class="QVBoxLayout" >
- <property name="margin" >
+ <property name="rightMargin" >
<number>0</number>
</property>
- <property name="spacing" >
- <number>6</number>
+ <property name="bottomMargin" >
+ <number>0</number>
</property>
<item>
- <widget class="QLabel" name="label" >
+ <widget class="QLabel" name="label_2" >
<property name="text" >
- <string>Capture Buses</string>
+ <string>Channels</string>
</property>
</widget>
</item>
<item>
- <widget class="QListWidget" name="busesListWidget" />
+ <widget class="QRadioButton" name="radioBoth" >
+ <property name="text" >
+ <string>Both</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="radioLeftOnly" >
+ <property name="text" >
+ <string>Left</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="radioRightOnly" >
+ <property name="text" >
+ <string>Right</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
</item>
</layout>
</item>
+ </layout>
+ </widget>
+ </item>
<item>
- <layout class="QVBoxLayout" >
- <property name="margin" >
- <number>0</number>
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Playback Buses</string>
</property>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QListWidget" name="busesListWidgetPlayback" />
+ </item>
+ <item>
+ <layout class="QVBoxLayout" >
<property name="spacing" >
<number>6</number>
</property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
<item>
- <widget class="QLabel" name="label_2" >
+ <widget class="QLabel" name="label_5" >
<property name="text" >
<string>Channels</string>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="radioBoth" >
+ <widget class="QRadioButton" name="radioBothPlayback" >
<property name="text" >
<string>Both</string>
</property>
@@ -110,14 +174,14 @@
</widget>
</item>
<item>
- <widget class="QRadioButton" name="radioLeftOnly" >
+ <widget class="QRadioButton" name="radioLeftOnlyPlayback" >
<property name="text" >
<string>Left</string>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="radioRightOnly" >
+ <widget class="QRadioButton" name="radioRightOnlyPlayback" >
<property name="text" >
<string>Right</string>
</property>
@@ -139,6 +203,7 @@
</layout>
</item>
</layout>
+ </widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox" >
- [Traverso-commit] traverso/src core/Song.cpp core/Song.h core/Tra...,
Remon Sijrier <=