diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:37:05 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:37:05 +0000 |
commit | 145364a8af6a1fec06556221e66d4b724a62fc9a (patch) | |
tree | 53bd71a544008c518034f208d64c932dc2883f50 /src/base/Studio.cpp | |
download | rosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.tar.gz rosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.zip |
Added old abandoned KDE3 version of the RoseGarden MIDI tool
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/rosegarden@1097595 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/base/Studio.cpp')
-rw-r--r-- | src/base/Studio.cpp | 674 |
1 files changed, 674 insertions, 0 deletions
diff --git a/src/base/Studio.cpp b/src/base/Studio.cpp new file mode 100644 index 0000000..89e7cc1 --- /dev/null +++ b/src/base/Studio.cpp @@ -0,0 +1,674 @@ +// -*- 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 <iostream> + +#include "Studio.h" +#include "MidiDevice.h" +#include "AudioDevice.h" +#include "Instrument.h" + +#include "Segment.h" +#include "Track.h" +#include "Composition.h" + +#if (__GNUC__ < 3) +#include <strstream> +#define stringstream strstream +#else +#include <sstream> +#endif + +using std::cerr; +using std::endl; + + +namespace Rosegarden +{ + +Studio::Studio() : + m_midiThruFilter(0), + m_midiRecordFilter(0), + m_mixerDisplayOptions(0), + m_metronomeDevice(0) +{ + // We _always_ have a buss with id zero, for the master out + m_busses.push_back(new Buss(0)); + + // And we always create one audio record in + m_recordIns.push_back(new RecordIn()); +} + +Studio::~Studio() +{ + DeviceListIterator dIt = m_devices.begin(); + + for (; dIt != m_devices.end(); ++dIt) + delete(*dIt); + + m_devices.clear(); + + for (size_t i = 0; i < m_busses.size(); ++i) { + delete m_busses[i]; + } + + for (size_t i = 0; i < m_recordIns.size(); ++i) { + delete m_recordIns[i]; + } +} + +void +Studio::addDevice(const std::string &name, + DeviceId id, + Device::DeviceType type) +{ + switch(type) + { + case Device::Midi: + m_devices.push_back(new MidiDevice(id, name, MidiDevice::Play)); + break; + + case Device::Audio: + m_devices.push_back(new AudioDevice(id, name)); + break; + + default: + std::cerr << "Studio::addDevice() - unrecognised device" + << endl; + break; + } +} + +void +Studio::addDevice(Device *device) +{ + m_devices.push_back(device); +} + +void +Studio::removeDevice(DeviceId id) +{ + DeviceListIterator it; + for (it = m_devices.begin(); it != m_devices.end(); it++) + { + if ((*it)->getId() == id) { + delete *it; + m_devices.erase(it); + return; + } + } +} + +InstrumentList +Studio::getAllInstruments() +{ + InstrumentList list, subList; + + DeviceListIterator it; + + // Append lists + // + for (it = m_devices.begin(); it != m_devices.end(); it++) + { + // get sub list + subList = (*it)->getAllInstruments(); + + // concetenate + list.insert(list.end(), subList.begin(), subList.end()); + } + + return list; + +} + +InstrumentList +Studio::getPresentationInstruments() +{ + InstrumentList list, subList; + + std::vector<Device*>::iterator it; + MidiDevice *midiDevice; + + // Append lists + // + for (it = m_devices.begin(); it != m_devices.end(); it++) + { + midiDevice = dynamic_cast<MidiDevice*>(*it); + + if (midiDevice) + { + // skip read-only devices + if (midiDevice->getDirection() == MidiDevice::Record) + continue; + } + + // get sub list + subList = (*it)->getPresentationInstruments(); + + // concatenate + list.insert(list.end(), subList.begin(), subList.end()); + } + + return list; + +} + +Instrument* +Studio::getInstrumentById(InstrumentId id) +{ + std::vector<Device*>::iterator it; + InstrumentList list; + InstrumentList::iterator iit; + + for (it = m_devices.begin(); it != m_devices.end(); it++) + { + list = (*it)->getAllInstruments(); + + for (iit = list.begin(); iit != list.end(); iit++) + if ((*iit)->getId() == id) + return (*iit); + } + + return 0; + +} + +// From a user selection (from a "Presentation" list) return +// the matching Instrument +// +Instrument* +Studio::getInstrumentFromList(int index) +{ + std::vector<Device*>::iterator it; + InstrumentList list; + InstrumentList::iterator iit; + int count = 0; + + for (it = m_devices.begin(); it != m_devices.end(); it++) + { + MidiDevice *midiDevice = dynamic_cast<MidiDevice*>(*it); + + if (midiDevice) + { + // skip read-only devices + if (midiDevice->getDirection() == MidiDevice::Record) + continue; + } + + list = (*it)->getPresentationInstruments(); + + for (iit = list.begin(); iit != list.end(); iit++) + { + if (count == index) + return (*iit); + + count++; + } + } + + return 0; + +} + +Instrument * +Studio::getInstrumentFor(Segment *segment) +{ + if (!segment) return 0; + if (!segment->getComposition()) return 0; + TrackId tid = segment->getTrack(); + Track *track = segment->getComposition()->getTrackById(tid); + if (!track) return 0; + return getInstrumentFor(track); +} + +Instrument * +Studio::getInstrumentFor(Track *track) +{ + if (!track) return 0; + InstrumentId iid = track->getInstrument(); + return getInstrumentById(iid); +} + +BussList +Studio::getBusses() +{ + return m_busses; +} + +Buss * +Studio::getBussById(BussId id) +{ + for (BussList::iterator i = m_busses.begin(); i != m_busses.end(); ++i) { + if ((*i)->getId() == id) return *i; + } + return 0; +} + +void +Studio::addBuss(Buss *buss) +{ + m_busses.push_back(buss); +} + +PluginContainer * +Studio::getContainerById(InstrumentId id) +{ + PluginContainer *pc = getInstrumentById(id); + if (pc) return pc; + else return getBussById(id); +} + +RecordIn * +Studio::getRecordIn(int number) +{ + if (number >= 0 && number < int(m_recordIns.size())) return m_recordIns[number]; + else return 0; +} + +// Clear down the devices - the devices will clear down their +// own Instruments. +// +void +Studio::clear() +{ + InstrumentList list; + std::vector<Device*>::iterator it; + + for (it = m_devices.begin(); it != m_devices.end(); it++) + delete *it; + + m_devices.erase(m_devices.begin(), m_devices.end()); +} + +std::string +Studio::toXmlString() +{ + return toXmlString(std::vector<DeviceId>()); +} + +std::string +Studio::toXmlString(const std::vector<DeviceId> &devices) +{ + std::stringstream studio; + + studio << "<studio thrufilter=\"" << m_midiThruFilter + << "\" recordfilter=\"" << m_midiRecordFilter + << "\" audioinputpairs=\"" << m_recordIns.size() + << "\" mixerdisplayoptions=\"" << m_mixerDisplayOptions + << "\" metronomedevice=\"" << m_metronomeDevice + << "\">" << endl << endl; + + studio << endl; + + InstrumentList list; + + // Get XML version of devices + // + if (devices.empty()) { // export all devices and busses + + for (DeviceListIterator it = m_devices.begin(); + it != m_devices.end(); it++) { + studio << (*it)->toXmlString() << endl << endl; + } + + for (BussList::iterator it = m_busses.begin(); + it != m_busses.end(); ++it) { + studio << (*it)->toXmlString() << endl << endl; + } + + } else { + for (std::vector<DeviceId>::const_iterator di(devices.begin()); + di != devices.end(); ++di) { + Device *d = getDevice(*di); + if (!d) { + std::cerr << "WARNING: Unknown device id " << (*di) + << " in Studio::toXmlString" << std::endl; + } else { + studio << d->toXmlString() << endl << endl; + } + } + } + + studio << endl << endl; + +#if (__GNUC__ < 3) + studio << "</studio>" << endl << std::ends; +#else + studio << "</studio>" << endl; +#endif + + return studio.str(); +} + +// Run through the Devices checking for MidiDevices and +// returning the first Metronome we come across +// +const MidiMetronome* +Studio::getMetronomeFromDevice(DeviceId id) +{ + std::vector<Device*>::iterator it; + MidiDevice *midiDevice; + + for (it = m_devices.begin(); it != m_devices.end(); it++) + { + midiDevice = dynamic_cast<MidiDevice*>(*it); + + if (midiDevice && + midiDevice->getId() == id && + midiDevice->getMetronome()) + { + return midiDevice->getMetronome(); + } + } + + return 0; +} + +// Scan all MIDI devices for available channels and map +// them to a current program + +Instrument* +Studio::assignMidiProgramToInstrument(MidiByte program, + int msb, int lsb, + bool percussion) +{ + MidiDevice *midiDevice; + std::vector<Device*>::iterator it; + Rosegarden::InstrumentList::iterator iit; + Rosegarden::InstrumentList instList; + + // Instruments that we may return + // + Rosegarden::Instrument *newInstrument = 0; + Rosegarden::Instrument *firstInstrument = 0; + + bool needBank = (msb >= 0 || lsb >= 0); + if (needBank) { + if (msb < 0) msb = 0; + if (lsb < 0) lsb = 0; + } + + // Pass one - search through all MIDI instruments looking for + // a match that we can re-use. i.e. if we have a matching + // Program Change then we can use this Instrument. + // + for (it = m_devices.begin(); it != m_devices.end(); it++) + { + midiDevice = dynamic_cast<MidiDevice*>(*it); + + if (midiDevice && midiDevice->getDirection() == MidiDevice::Play) + { + instList = (*it)->getPresentationInstruments(); + + for (iit = instList.begin(); iit != instList.end(); iit++) + { + if (firstInstrument == 0) + firstInstrument = *iit; + + // If we find an Instrument sending the right program already. + // + if ((*iit)->sendsProgramChange() && + (*iit)->getProgramChange() == program && + (!needBank || ((*iit)->sendsBankSelect() && + (*iit)->getMSB() == msb && + (*iit)->getLSB() == lsb && + (*iit)->isPercussion() == percussion))) + { + return (*iit); + } + else + { + // Ignore the program change and use the percussion + // flag. + // + if ((*iit)->isPercussion() && percussion) + { + return (*iit); + } + + // Otherwise store the first Instrument for + // possible use later. + // + if (newInstrument == 0 && + (*iit)->sendsProgramChange() == false && + (*iit)->sendsBankSelect() == false && + (*iit)->isPercussion() == percussion) + newInstrument = *iit; + } + } + } + } + + + // Okay, if we've got this far and we have a new Instrument to use + // then use it. + // + if (newInstrument != 0) + { + newInstrument->setSendProgramChange(true); + newInstrument->setProgramChange(program); + + if (needBank) { + newInstrument->setSendBankSelect(true); + newInstrument->setPercussion(percussion); + newInstrument->setMSB(msb); + newInstrument->setLSB(lsb); + } + } + else // Otherwise we just reuse the first Instrument we found + newInstrument = firstInstrument; + + + return newInstrument; +} + +// Just make all of these Instruments available for automatic +// assignment in the assignMidiProgramToInstrument() method +// by invalidating the ProgramChange flag. +// +// This method sounds much more dramatic than it actually is - +// it could probably do with a rename. +// +// +void +Studio::unassignAllInstruments() +{ + MidiDevice *midiDevice; + AudioDevice *audioDevice; + std::vector<Device*>::iterator it; + Rosegarden::InstrumentList::iterator iit; + Rosegarden::InstrumentList instList; + int channel = 0; + + for (it = m_devices.begin(); it != m_devices.end(); it++) + { + midiDevice = dynamic_cast<MidiDevice*>(*it); + + if (midiDevice) + { + instList = (*it)->getPresentationInstruments(); + + for (iit = instList.begin(); iit != instList.end(); iit++) + { + // Only for true MIDI Instruments - not System ones + // + if ((*iit)->getId() >= MidiInstrumentBase) + { + (*iit)->setSendBankSelect(false); + (*iit)->setSendProgramChange(false); + (*iit)->setMidiChannel(channel); + channel = ( channel + 1 ) % 16; + + (*iit)->setSendPan(false); + (*iit)->setSendVolume(false); + (*iit)->setPan(MidiMidValue); + (*iit)->setVolume(100); + + } + } + } + else + { + audioDevice = dynamic_cast<AudioDevice*>(*it); + + if (audioDevice) + { + instList = (*it)->getPresentationInstruments(); + + for (iit = instList.begin(); iit != instList.end(); iit++) + (*iit)->emptyPlugins(); + } + } + } +} + +void +Studio::clearMidiBanksAndPrograms() +{ + MidiDevice *midiDevice; + std::vector<Device*>::iterator it; + + for (it = m_devices.begin(); it != m_devices.end(); it++) + { + midiDevice = dynamic_cast<MidiDevice*>(*it); + + if (midiDevice) + { + midiDevice->clearProgramList(); + midiDevice->clearBankList(); + } + } +} + +void +Studio::clearBusses() +{ + for (size_t i = 0; i < m_busses.size(); ++i) { + delete m_busses[i]; + } + m_busses.clear(); + m_busses.push_back(new Buss(0)); +} + +void +Studio::clearRecordIns() +{ + for (size_t i = 0; i < m_recordIns.size(); ++i) { + delete m_recordIns[i]; + } + m_recordIns.clear(); + m_recordIns.push_back(new RecordIn()); +} + +Device* +Studio::getDevice(DeviceId id) +{ + //cerr << "Studio[" << this << "]::getDevice(" << id << ")... "; + + std::vector<Device*>::iterator it; + + for (it = m_devices.begin(); it != m_devices.end(); it++) { + +// if (it != m_devices.begin()) cerr << ", "; + +// cerr << (*it)->getId(); + if ((*it)->getId() == id) { + //cerr << ". Found" << endl; + return (*it); + } + } + + //cerr << ". Not found" << endl; + + return 0; +} + +std::string +Studio::getSegmentName(InstrumentId id) +{ + MidiDevice *midiDevice; + std::vector<Device*>::iterator it; + Rosegarden::InstrumentList::iterator iit; + Rosegarden::InstrumentList instList; + + for (it = m_devices.begin(); it != m_devices.end(); it++) + { + midiDevice = dynamic_cast<MidiDevice*>(*it); + + if (midiDevice) + { + instList = (*it)->getAllInstruments(); + + for (iit = instList.begin(); iit != instList.end(); iit++) + { + if ((*iit)->getId() == id) + { + if ((*iit)->sendsProgramChange()) + { + return (*iit)->getProgramName(); + } + else + { + return midiDevice->getName() + " " + (*iit)->getName(); + } + } + } + } + } + + return std::string(""); +} + +InstrumentId +Studio::getAudioPreviewInstrument() +{ + AudioDevice *audioDevice; + std::vector<Device*>::iterator it; + + for (it = m_devices.begin(); it != m_devices.end(); it++) + { + audioDevice = dynamic_cast<AudioDevice*>(*it); + + // Just the first one will do - we can make this more + // subtle if we need to later. + // + if (audioDevice) + return audioDevice->getPreviewInstrument(); + } + + // system instrument - won't accept audio + return 0; +} + +bool +Studio::haveMidiDevices() const +{ + Rosegarden::DeviceListConstIterator it = m_devices.begin(); + for (; it != m_devices.end(); it++) + { + if ((*it)->getType() == Device::Midi) return true; + } + return false; +} + + +} + |