summaryrefslogtreecommitdiffstats
path: root/src/sound/SequencerDataBlock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sound/SequencerDataBlock.cpp')
-rw-r--r--src/sound/SequencerDataBlock.cpp361
1 files changed, 361 insertions, 0 deletions
diff --git a/src/sound/SequencerDataBlock.cpp b/src/sound/SequencerDataBlock.cpp
new file mode 100644
index 0000000..bc5e80b
--- /dev/null
+++ b/src/sound/SequencerDataBlock.cpp
@@ -0,0 +1,361 @@
+// -*- c-basic-offset: 4 -*-
+
+/*
+ Rosegarden
+ A sequencer and musical notation editor.
+
+ This program is Copyright 2000-2008
+ Guillaume Laurent <[email protected]>,
+ Chris Cannam <[email protected]>,
+ Richard Bown <[email protected]>
+
+ The moral right of the authors to claim authorship of this work
+ has been asserted.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version. See the file
+ COPYING included with this distribution for more information.
+*/
+
+#include "SequencerDataBlock.h"
+#include "MappedComposition.h"
+
+namespace Rosegarden
+{
+
+SequencerDataBlock::SequencerDataBlock(bool initialise)
+{
+ if (initialise)
+ clearTemporaries();
+}
+
+bool
+SequencerDataBlock::getVisual(MappedEvent &ev) const
+{
+ static int eventIndex = 0;
+
+ if (!m_haveVisualEvent) {
+ return false;
+ } else {
+ int thisEventIndex = m_visualEventIndex;
+ if (thisEventIndex == eventIndex)
+ return false;
+ ev = *((MappedEvent *) & m_visualEvent);
+ eventIndex = thisEventIndex;
+ return true;
+ }
+}
+
+void
+SequencerDataBlock::setVisual(const MappedEvent *ev)
+{
+ m_haveVisualEvent = false;
+ if (ev) {
+ *((MappedEvent *)&m_visualEvent) = *ev;
+ ++m_visualEventIndex;
+ m_haveVisualEvent = true;
+ }
+}
+
+int
+SequencerDataBlock::getRecordedEvents(MappedComposition &mC) const
+{
+ static int readIndex = -1;
+
+ if (readIndex == -1) {
+ readIndex = m_recordEventIndex;
+ return 0;
+ }
+
+ int currentIndex = m_recordEventIndex;
+ int count = 0;
+
+ MappedEvent *recordBuffer = (MappedEvent *)m_recordBuffer;
+
+ while (readIndex != currentIndex) {
+ mC.insert(new MappedEvent(recordBuffer[readIndex]));
+ if (++readIndex == SEQUENCER_DATABLOCK_RECORD_BUFFER_SIZE)
+ readIndex = 0;
+ ++count;
+ }
+
+ return count;
+}
+
+void
+SequencerDataBlock::addRecordedEvents(MappedComposition *mC)
+{
+ // ringbuffer
+ int index = m_recordEventIndex;
+ MappedEvent *recordBuffer = (MappedEvent *)m_recordBuffer;
+
+ for (MappedComposition::iterator i = mC->begin(); i != mC->end(); ++i) {
+ recordBuffer[index] = **i;
+ if (++index == SEQUENCER_DATABLOCK_RECORD_BUFFER_SIZE)
+ index = 0;
+ }
+
+ m_recordEventIndex = index;
+}
+
+int
+SequencerDataBlock::instrumentToIndex(InstrumentId id) const
+{
+ int i;
+
+ for (i = 0; i < m_knownInstrumentCount; ++i) {
+ if (m_knownInstruments[i] == id)
+ return i;
+ }
+
+ return -1;
+}
+
+int
+SequencerDataBlock::instrumentToIndexCreating(InstrumentId id)
+{
+ int i;
+
+ for (i = 0; i < m_knownInstrumentCount; ++i) {
+ if (m_knownInstruments[i] == id)
+ return i;
+ }
+
+ if (i == SEQUENCER_DATABLOCK_MAX_NB_INSTRUMENTS) {
+ std::cerr << "ERROR: SequencerDataBlock::instrumentToIndexCreating("
+ << id << "): out of instrument index space" << std::endl;
+ return -1;
+ }
+
+ m_knownInstruments[i] = id;
+ ++m_knownInstrumentCount;
+ return i;
+}
+
+bool
+SequencerDataBlock::getInstrumentLevel(InstrumentId id,
+ LevelInfo &info) const
+{
+ static int lastUpdateIndex[SEQUENCER_DATABLOCK_MAX_NB_INSTRUMENTS];
+
+ int index = instrumentToIndex(id);
+ if (index < 0) {
+ info.level = info.levelRight = 0;
+ return false;
+ }
+
+ int currentUpdateIndex = m_levelUpdateIndices[index];
+ info = m_levels[index];
+
+ /*
+ std::cout << "SequencerDataBlock::getInstrumentLevel - "
+ << "id = " << id
+ << ", level = " << info.level << std::endl;
+ */
+
+ if (lastUpdateIndex[index] != currentUpdateIndex) {
+ lastUpdateIndex[index] = currentUpdateIndex;
+ return true;
+ } else {
+ return false; // no change
+ }
+}
+
+bool
+SequencerDataBlock::getInstrumentLevelForMixer(InstrumentId id,
+ LevelInfo &info) const
+{
+ static int lastUpdateIndex[SEQUENCER_DATABLOCK_MAX_NB_INSTRUMENTS];
+
+ int index = instrumentToIndex(id);
+ if (index < 0) {
+ info.level = info.levelRight = 0;
+ return false;
+ }
+
+ int currentUpdateIndex = m_levelUpdateIndices[index];
+ info = m_levels[index];
+
+ if (lastUpdateIndex[index] != currentUpdateIndex) {
+ lastUpdateIndex[index] = currentUpdateIndex;
+ return true;
+ } else {
+ return false; // no change
+ }
+}
+
+void
+SequencerDataBlock::setInstrumentLevel(InstrumentId id, const LevelInfo &info)
+{
+ int index = instrumentToIndexCreating(id);
+ if (index < 0)
+ return ;
+
+ m_levels[index] = info;
+ ++m_levelUpdateIndices[index];
+}
+
+bool
+SequencerDataBlock::getInstrumentRecordLevel(InstrumentId id, LevelInfo &info) const
+{
+ static int lastUpdateIndex[SEQUENCER_DATABLOCK_MAX_NB_INSTRUMENTS];
+
+ int index = instrumentToIndex(id);
+ if (index < 0) {
+ info.level = info.levelRight = 0;
+ return false;
+ }
+
+ int currentUpdateIndex = m_recordLevelUpdateIndices[index];
+ info = m_recordLevels[index];
+
+ if (lastUpdateIndex[index] != currentUpdateIndex) {
+ lastUpdateIndex[index] = currentUpdateIndex;
+ return true;
+ } else {
+ return false; // no change
+ }
+}
+
+bool
+SequencerDataBlock::getInstrumentRecordLevelForMixer(InstrumentId id, LevelInfo &info) const
+{
+ static int lastUpdateIndex[SEQUENCER_DATABLOCK_MAX_NB_INSTRUMENTS];
+
+ int index = instrumentToIndex(id);
+ if (index < 0) {
+ info.level = info.levelRight = 0;
+ return false;
+ }
+
+ int currentUpdateIndex = m_recordLevelUpdateIndices[index];
+ info = m_recordLevels[index];
+
+ if (lastUpdateIndex[index] != currentUpdateIndex) {
+ lastUpdateIndex[index] = currentUpdateIndex;
+ return true;
+ } else {
+ return false; // no change
+ }
+}
+
+void
+SequencerDataBlock::setInstrumentRecordLevel(InstrumentId id, const LevelInfo &info)
+{
+ int index = instrumentToIndexCreating(id);
+ if (index < 0)
+ return ;
+
+ m_recordLevels[index] = info;
+ ++m_recordLevelUpdateIndices[index];
+}
+
+void
+SequencerDataBlock::setTrackLevel(TrackId id, const LevelInfo &info)
+{
+ if (m_controlBlock) {
+ setInstrumentLevel(m_controlBlock->getInstrumentForTrack(id), info);
+ }
+}
+
+bool
+SequencerDataBlock::getTrackLevel(TrackId id, LevelInfo &info) const
+{
+ info.level = info.levelRight = 0;
+
+ if (m_controlBlock) {
+ return getInstrumentLevel(m_controlBlock->getInstrumentForTrack(id),
+ info);
+ }
+
+ return false;
+}
+
+bool
+SequencerDataBlock::getSubmasterLevel(int submaster, LevelInfo &info) const
+{
+ static int lastUpdateIndex[SEQUENCER_DATABLOCK_MAX_NB_SUBMASTERS];
+
+ if (submaster < 0 || submaster > SEQUENCER_DATABLOCK_MAX_NB_SUBMASTERS) {
+ info.level = info.levelRight = 0;
+ return false;
+ }
+
+ int currentUpdateIndex = m_submasterLevelUpdateIndices[submaster];
+ info = m_submasterLevels[submaster];
+
+ if (lastUpdateIndex[submaster] != currentUpdateIndex) {
+ lastUpdateIndex[submaster] = currentUpdateIndex;
+ return true;
+ } else {
+ return false; // no change
+ }
+}
+
+void
+SequencerDataBlock::setSubmasterLevel(int submaster, const LevelInfo &info)
+{
+ if (submaster < 0 || submaster > SEQUENCER_DATABLOCK_MAX_NB_SUBMASTERS) {
+ return ;
+ }
+
+ m_submasterLevels[submaster] = info;
+ ++m_submasterLevelUpdateIndices[submaster];
+}
+
+bool
+SequencerDataBlock::getMasterLevel(LevelInfo &level) const
+{
+ static int lastUpdateIndex = 0;
+
+ int currentIndex = m_masterLevelUpdateIndex;
+ level = m_masterLevel;
+
+ if (lastUpdateIndex != currentIndex) {
+ lastUpdateIndex = currentIndex;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void
+SequencerDataBlock::setMasterLevel(const LevelInfo &info)
+{
+ m_masterLevel = info;
+ ++m_masterLevelUpdateIndex;
+}
+
+void
+SequencerDataBlock::clearTemporaries()
+{
+ m_controlBlock = 0;
+ m_positionSec = 0;
+ m_positionNsec = 0;
+ m_visualEventIndex = 0;
+ *((MappedEvent *)&m_visualEvent) = MappedEvent();
+ m_haveVisualEvent = false;
+ m_recordEventIndex = 0;
+ //!!! m_recordLevel.level = 0;
+ //!!! m_recordLevel.levelRight = 0;
+ memset(m_knownInstruments, 0,
+ SEQUENCER_DATABLOCK_MAX_NB_INSTRUMENTS * sizeof(InstrumentId));
+ m_knownInstrumentCount = 0;
+ memset(m_levelUpdateIndices, 0,
+ SEQUENCER_DATABLOCK_MAX_NB_INSTRUMENTS * sizeof(int));
+ memset(m_levels, 0,
+ SEQUENCER_DATABLOCK_MAX_NB_INSTRUMENTS * sizeof(LevelInfo));
+ memset(m_submasterLevelUpdateIndices, 0,
+ SEQUENCER_DATABLOCK_MAX_NB_SUBMASTERS * sizeof(int));
+ memset(m_submasterLevels, 0,
+ SEQUENCER_DATABLOCK_MAX_NB_SUBMASTERS * sizeof(LevelInfo));
+ m_masterLevelUpdateIndex = 0;
+ m_masterLevel.level = 0;
+ m_masterLevel.levelRight = 0;
+
+}
+
+}
+