diff options
Diffstat (limited to 'muse_qt4_evolution/muse/audiooutput.cpp')
-rw-r--r-- | muse_qt4_evolution/muse/audiooutput.cpp | 191 |
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 + } + |