Mercurial > hg > svapp
diff framework/MainWindowBase.cpp @ 482:01669adb0956 tony-2.0-integration
Merge through to branch for Tony 2.0
author | Chris Cannam |
---|---|
date | Thu, 20 Aug 2015 14:54:21 +0100 |
parents | 52c0aff69478 |
children | 01aeda073720 111e976f9ed4 |
line wrap: on
line diff
--- a/framework/MainWindowBase.cpp Mon Apr 13 13:52:05 2015 +0100 +++ b/framework/MainWindowBase.cpp Thu Aug 20 14:54:21 2015 +0100 @@ -16,10 +16,10 @@ #include "MainWindowBase.h" #include "Document.h" - #include "view/Pane.h" #include "view/PaneStack.h" -#include "data/model/WaveFileModel.h" +#include "data/model/ReadOnlyWaveFileModel.h" +#include "data/model/WritableWaveFileModel.h" #include "data/model/SparseOneDimensionalModel.h" #include "data/model/NoteModel.h" #include "data/model/FlexiNoteModel.h" @@ -47,10 +47,10 @@ #include "widgets/ModelDataTableDialog.h" #include "widgets/InteractiveFileFinder.h" -#include "audioio/AudioCallbackPlaySource.h" -#include "audioio/AudioCallbackPlayTarget.h" -#include "audioio/AudioTargetFactory.h" -#include "audioio/PlaySpeedRangeMapper.h" +#include "audio/AudioCallbackPlaySource.h" +#include "audio/AudioRecordTarget.h" +#include "audio/PlaySpeedRangeMapper.h" + #include "data/fileio/DataFileReaderFactory.h" #include "data/fileio/PlaylistFileReader.h" #include "data/fileio/WavFileWriter.h" @@ -60,8 +60,6 @@ #include "data/fileio/AudioFileReaderFactory.h" #include "rdf/RDFImporter.h" -#include "data/fft/FFTDataServer.h" - #include "base/RecentFiles.h" #include "base/PlayParameterRepository.h" @@ -75,6 +73,10 @@ #include "data/osc/OSCQueue.h" #include "data/midi/MIDIInput.h" +#include <bqaudioio/SystemPlaybackTarget.h> +#include <bqaudioio/SystemAudioIO.h> +#include <bqaudioio/AudioFactory.h> + #include <QApplication> #include <QMessageBox> #include <QGridLayout> @@ -131,15 +133,16 @@ #undef Window #endif -MainWindowBase::MainWindowBase(bool withAudioOutput, - bool withMIDIInput) : +MainWindowBase::MainWindowBase(SoundOptions options) : m_document(0), m_paneStack(0), m_viewManager(0), m_timeRulerLayer(0), - m_audioOutput(withAudioOutput), + m_soundOptions(options), m_playSource(0), + m_recordTarget(0), m_playTarget(0), + m_audioIO(0), m_oscQueue(0), m_oscQueueStarter(0), m_midiInput(0), @@ -157,6 +160,12 @@ { Profiler profiler("MainWindowBase::MainWindowBase"); + if (options & WithAudioInput) { + if (!(options & WithAudioOutput)) { + cerr << "WARNING: MainWindowBase: WithAudioInput requires WithAudioOutput -- recording will not work" << endl; + } + } + qRegisterMetaType<sv_frame_t>("sv_frame_t"); qRegisterMetaType<sv_samplerate_t>("sv_samplerate_t"); @@ -164,6 +173,8 @@ XSetErrorHandler(handle_x11_error); #endif + connect(this, SIGNAL(hideSplash()), this, SLOT(emitHideSplash())); + connect(CommandHistory::getInstance(), SIGNAL(commandExecuted()), this, SLOT(documentModified())); connect(CommandHistory::getInstance(), SIGNAL(documentRestored()), @@ -216,6 +227,10 @@ m_playSource = new AudioCallbackPlaySource(m_viewManager, QApplication::applicationName()); + if (m_soundOptions & WithAudioInput) { + m_recordTarget = new AudioRecordTarget(m_viewManager, + QApplication::applicationName()); + } connect(m_playSource, SIGNAL(sampleRateMismatch(sv_samplerate_t, sv_samplerate_t, bool)), this, SLOT(sampleRateMismatch(sv_samplerate_t, sv_samplerate_t, bool))); @@ -256,17 +271,20 @@ m_labeller = new Labeller(labellerType); m_labeller->setCounterCycleSize(cycle); - if (withMIDIInput) { + if (m_soundOptions & WithMIDIInput) { m_midiInput = new MIDIInput(QApplication::applicationName(), this); } + + QTimer::singleShot(1500, this, SIGNAL(hideSplash())); } MainWindowBase::~MainWindowBase() { SVDEBUG << "MainWindowBase::~MainWindowBase" << endl; - if (m_playTarget) m_playTarget->shutdown(); -// delete m_playTarget; + delete m_playTarget; delete m_playSource; + delete m_audioIO; + delete m_recordTarget; delete m_viewManager; delete m_oscQueue; delete m_oscQueueStarter; @@ -275,6 +293,12 @@ } void +MainWindowBase::emitHideSplash() +{ + emit hideSplash(this); +} + +void MainWindowBase::finaliseMenus() { delete m_menuShortcutMapper; @@ -542,7 +566,7 @@ bool haveMainModel = (getMainModel() != 0); bool havePlayTarget = - (m_playTarget != 0); + (m_playTarget != 0 || m_audioIO != 0); bool haveSelection = (m_viewManager && !m_viewManager->getSelections().empty()); @@ -587,8 +611,9 @@ emit canMeasureLayer(haveCurrentLayer); emit canSelect(haveMainModel && haveCurrentPane); emit canPlay(haveMainModel && havePlayTarget); - emit canFfwd(true); - emit canRewind(true); + emit canRecord(m_soundOptions & WithAudioInput); // always possible then + emit canFfwd(haveMainModel); + emit canRewind(haveMainModel); emit canPaste(haveClipboardContents); emit canInsertInstant(haveCurrentPane); emit canInsertInstantsAtBoundaries(haveCurrentPane && haveSelection); @@ -1303,7 +1328,7 @@ rate = m_playSource->getSourceSampleRate(); } - WaveFileModel *newModel = new WaveFileModel(source, rate); + ReadOnlyWaveFileModel *newModel = new ReadOnlyWaveFileModel(source, rate); if (!newModel->isOK()) { delete newModel; @@ -2150,28 +2175,42 @@ } void -MainWindowBase::createPlayTarget() +MainWindowBase::createAudioIO() { - if (m_playTarget) return; - + if (m_playTarget || m_audioIO) return; + + if (!(m_soundOptions & WithAudioOutput)) return; + + //!!! how to handle preferences +/* QSettings settings; settings.beginGroup("Preferences"); QString targetName = settings.value("audio-target", "").toString(); settings.endGroup(); - AudioTargetFactory *factory = AudioTargetFactory::getInstance(); factory->setDefaultCallbackTarget(targetName); - m_playTarget = factory->createCallbackTarget(m_playSource); - - if (!m_playTarget) { +*/ + + if (m_soundOptions & WithAudioInput) { + m_audioIO = breakfastquay::AudioFactory:: + createCallbackIO(m_recordTarget, m_playSource); + m_playSource->setSystemPlaybackTarget(m_audioIO); + } else { + m_playTarget = breakfastquay::AudioFactory:: + createCallbackPlayTarget(m_playSource); + m_playSource->setSystemPlaybackTarget(m_playTarget); + } + + if (!m_playTarget && !m_audioIO) { emit hideSplash(); - if (factory->isAutoCallbackTarget(targetName)) { +// if (factory->isAutoCallbackTarget(targetName)) { QMessageBox::warning (this, tr("Couldn't open audio device"), tr("<b>No audio available</b><p>Could not open an audio device for playback.<p>Automatic audio device detection failed. Audio playback will not be available during this session.</p>"), QMessageBox::Ok); +/* } else { QMessageBox::warning (this, tr("Couldn't open audio device"), @@ -2179,6 +2218,8 @@ .arg(factory->getCallbackTargetDescription(targetName)), QMessageBox::Ok); } +*/ + return; } } @@ -2610,8 +2651,10 @@ void MainWindowBase::play() { - if (m_playSource->isPlaying()) { + if (m_recordTarget->isRecording() || m_playSource->isPlaying()) { stop(); + QAction *action = qobject_cast<QAction *>(sender()); + if (action) action->setChecked(false); } else { playbackFrameChanged(m_viewManager->getPlaybackFrame()); m_playSource->play(m_viewManager->getPlaybackFrame()); @@ -2619,6 +2662,124 @@ } void +MainWindowBase::record() +{ + if (!(m_soundOptions & WithAudioInput)) { + return; + } + + if (!m_recordTarget) { + //!!! report + return; + } + + if (!m_audioIO) { + createAudioIO(); + } + + if (m_recordTarget->isRecording()) { + m_recordTarget->stopRecording(); + emit audioFileLoaded(); + return; + } + + WritableWaveFileModel *model = m_recordTarget->startRecording(); + if (!model) { + cerr << "ERROR: MainWindowBase::record: Recording failed" << endl; + //!!! report + return; + } + + if (!model->isOK()) { + m_recordTarget->stopRecording(); + delete model; + //!!! ??? + return; + } + + PlayParameterRepository::getInstance()->addPlayable(model); + + if (!getMainModel()) { + + //!!! duplication with openAudio here + + QString templateName = getDefaultSessionTemplate(); + bool loadedTemplate = false; + + if (templateName != "") { + FileOpenStatus tplStatus = openSessionTemplate(templateName); + if (tplStatus == FileOpenCancelled) { + return; + } + if (tplStatus != FileOpenFailed) { + loadedTemplate = true; + } + } + + if (!loadedTemplate) { + closeSession(); + createDocument(); + } + + Model *prevMain = getMainModel(); + if (prevMain) { + m_playSource->removeModel(prevMain); + PlayParameterRepository::getInstance()->removePlayable(prevMain); + } + + m_document->setMainModel(model); + setupMenus(); + + if (loadedTemplate || (m_sessionFile == "")) { + //!!! shouldn't be dealing directly with title from here -- call a method + setWindowTitle(tr("%1: %2") + .arg(QApplication::applicationName()) + .arg(model->getLocation())); + CommandHistory::getInstance()->clear(); + CommandHistory::getInstance()->documentSaved(); + m_documentModified = false; + } else { + setWindowTitle(tr("%1: %2 [%3]") + .arg(QApplication::applicationName()) + .arg(QFileInfo(m_sessionFile).fileName()) + .arg(model->getLocation())); + if (m_documentModified) { + m_documentModified = false; + documentModified(); // so as to restore "(modified)" window title + } + } + + } else { + + CommandHistory::getInstance()->startCompoundOperation + (tr("Import Recorded Audio"), true); + + m_document->addImportedModel(model); + + AddPaneCommand *command = new AddPaneCommand(this); + CommandHistory::getInstance()->addCommand(command); + + Pane *pane = command->getPane(); + + if (m_timeRulerLayer) { + m_document->addLayerToView(pane, m_timeRulerLayer); + } + + Layer *newLayer = m_document->createImportedLayer(model); + + if (newLayer) { + m_document->addLayerToView(pane, newLayer); + } + + CommandHistory::getInstance()->endCompoundOperation(); + } + + updateMenuStates(); + m_recentFiles.addFile(model->getLocation()); + currentPaneChanged(m_paneStack->getCurrentPane()); +} + +void MainWindowBase::ffwd() { if (!getMainModel()) return; @@ -2846,6 +3007,11 @@ void MainWindowBase::stop() { + if (m_recordTarget->isRecording()) { + m_recordTarget->stopRecording(); + emit audioFileLoaded(); + } + m_playSource->stop(); if (m_paneStack && m_paneStack->getCurrentPane()) { @@ -3316,8 +3482,9 @@ // SVDEBUG << "MainWindowBase::mainModelChanged(" << model << ")" << endl; updateDescriptionLabel(); if (model) m_viewManager->setMainModelSampleRate(model->getSampleRate()); - if (model && !m_playTarget && m_audioOutput) { - createPlayTarget(); + if (model && !(m_playTarget || m_audioIO) && + (m_soundOptions & WithAudioOutput)) { + createAudioIO(); } } @@ -3329,7 +3496,6 @@ m_viewManager->setPlaybackModel(0); } m_playSource->removeModel(model); - FFTDataServer::modelAboutToBeDeleted(model); } void