You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
rosegarden/src/sound/SequencerDataBlock.cpp

360 lines
8.9 KiB

/*
Rosegarden
A sequencer and musical notation editor.
This program is Copyright 2000-2008
Guillaume Laurent <glaurent@telegraph-road.org>,
Chris Cannam <cannam@all-day-breakfast.com>,
Richard Bown <bownie@bownie.com>
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;
}
}