summaryrefslogtreecommitdiff
path: root/muse_qt4_evolution/muse/audiooutput.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse_qt4_evolution/muse/audiooutput.cpp')
-rw-r--r--muse_qt4_evolution/muse/audiooutput.cpp191
1 files changed, 191 insertions, 0 deletions
diff --git a/muse_qt4_evolution/muse/audiooutput.cpp b/muse_qt4_evolution/muse/audiooutput.cpp
new file mode 100644
index 00000000..e4937a74
--- /dev/null
+++ b/muse_qt4_evolution/muse/audiooutput.cpp
@@ -0,0 +1,191 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "audiooutput.h"
+#include "jackaudio.h"
+#include "audio.h"
+#include "globals.h"
+#include "song.h"
+#include "ticksynth.h"
+
+//---------------------------------------------------------
+// AudioOutput
+//---------------------------------------------------------
+
+AudioOutput::AudioOutput()
+ : AudioTrack()
+ {
+ _channels = 0;
+ setChannels(2);
+
+ //
+ // buffers are allocated from AudioTrack()
+ // and not needed by AudioOutput which uses
+ // the JACK supplied buffers
+
+ for (int i = 0; i < MAX_CHANNELS; ++i) {
+ if (buffer[i]) {
+ free(buffer[i]);
+ buffer[i] = 0;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// ~AudioOutput
+//---------------------------------------------------------
+
+AudioOutput::~AudioOutput()
+ {
+ for (int i = 0; i < _channels; ++i) {
+ if (!jackPort(i).isZero())
+ audioDriver->unregisterPort(jackPort(i));
+ }
+ // AudioOutput does not own buffers (they are from JACK)
+ // make sure ~AudioTrack() does not delete them:
+ for (int i = 0; i < MAX_CHANNELS; ++i)
+ buffer[i] = 0;
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void AudioOutput::write(Xml& xml) const
+ {
+ xml.stag("AudioOutput");
+ AudioTrack::writeProperties(xml);
+ xml.etag("AudioOutput");
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void AudioOutput::read(QDomNode node)
+ {
+ while (!node.isNull()) {
+ AudioTrack::readProperties(node);
+ node = node.nextSibling();
+ }
+ setName(name()); // allocate jack ports
+ }
+
+//---------------------------------------------------------
+// setChannels
+//---------------------------------------------------------
+
+void AudioOutput::setChannels(int n)
+ {
+ if (n == _channels)
+ return;
+ AudioTrack::setChannels(n);
+ }
+
+//---------------------------------------------------------
+// silence
+//---------------------------------------------------------
+
+void AudioOutput::silence(unsigned n)
+ {
+ for (int i = 0; i < channels(); ++i) {
+ if (!jackPort(i).isZero())
+ buffer[i] = audioDriver->getBuffer(jackPort(i), n);
+ else {
+ printf("PANIC: silence(): no buffer from audio driver\n");
+ abort();
+ return;
+ }
+ }
+ for (int i = 0; i < channels(); ++i)
+ memset(buffer[i], 0, n * sizeof(float));
+ }
+
+//---------------------------------------------------------
+// setName
+//---------------------------------------------------------
+
+void AudioOutput::setName(const QString& s)
+ {
+ Track::setName(s);
+ for (int i = 0; i < channels(); ++i) {
+ if (!jackPort(i).isZero()) {
+ char buffer[128];
+ snprintf(buffer, 128, "%s-%d", _name.toAscii().data(), i);
+ audioDriver->setPortName(jackPort(i), buffer);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// stopRecording
+// gui context
+//---------------------------------------------------------
+
+void AudioOutput::stopRecording(const Pos& /*s*/, const Pos& /*e*/)
+ {
+ SndFile* sf = recFile();
+ if (sf)
+ delete sf; // close
+ setRecFile(0);
+ setRecordFlag(false);
+ }
+
+//---------------------------------------------------------
+// process
+// synthesize segmentSize frames at buffer offset "offset"
+// current frame position is "pos"
+//---------------------------------------------------------
+
+void AudioOutput::process()
+ {
+ for (int c = 0; c < channels(); ++c)
+ buffer[c] = audioDriver->getBuffer(jackPort(c), segmentSize);
+
+ AudioTrack::process();
+
+ if (bufferEmpty) {
+ for (int c = 0; c < channels(); ++c)
+ memset(buffer[c], 0, sizeof(float) * segmentSize);
+ }
+
+ int n = segmentSize;
+ if (audio->isRecording() && recordFlag() && _recFile) {
+ // bounce to file
+ if (audio->freewheel())
+ _recFile->write(channels(), buffer, n);
+ else
+ putFifo(channels(), n, buffer);
+ }
+
+#if 0
+ if (audioClickFlag && song->click() && metronome) {
+ float b[n];
+ float* bp[1];
+ bp[0] = b;
+ metronome->getData(pos, 1, n, bp);
+ for (unsigned i = 0; i < n; ++i) {
+ for (int k = 0; k < channels(); ++k)
+ buffer[k][i] += b[i] * audioClickVolume;
+ }
+ }
+#endif
+ }
+