diff options
author | Michele Calgaro <michele.calgaro@yahoo.it> | 2020-12-08 22:26:17 +0900 |
---|---|---|
committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2020-12-08 22:49:18 +0900 |
commit | 2fe8b1b92fa2a9b93fea0ed0cb62802237b82e8d (patch) | |
tree | 50b6e05734cd5c0f642eeac4e841539db25f113b /arts/modules/synth/synth_midi_test_impl.cc | |
parent | 6f9d8ae25c3ff607e0e07315884c967dd0bca901 (diff) | |
download | tdemultimedia-2fe8b1b92fa2a9b93fea0ed0cb62802237b82e8d.tar.gz tdemultimedia-2fe8b1b92fa2a9b93fea0ed0cb62802237b82e8d.zip |
Renaming of files in preparation for code style tools.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
(cherry picked from commit fce86b22a2367f1be1f9aae5e1ba3d18d1371b74)
Diffstat (limited to 'arts/modules/synth/synth_midi_test_impl.cc')
-rw-r--r-- | arts/modules/synth/synth_midi_test_impl.cc | 692 |
1 files changed, 0 insertions, 692 deletions
diff --git a/arts/modules/synth/synth_midi_test_impl.cc b/arts/modules/synth/synth_midi_test_impl.cc deleted file mode 100644 index 91714cac..00000000 --- a/arts/modules/synth/synth_midi_test_impl.cc +++ /dev/null @@ -1,692 +0,0 @@ -#include "artsmodulessynth.h" -#include "artsbuilder.h" -#include "stdsynthmodule.h" -#include "objectmanager.h" -#include "connect.h" -#include "flowsystem.h" -#include "debug.h" -#include "dynamicrequest.h" -#include "audiosubsys.h" -#include <fstream> -#include <math.h> -#include <stdlib.h> - -using namespace Arts; -using namespace std; - -/*-------- instrument mapping ---------*/ - -class InstrumentMap { -protected: - struct InstrumentData; - class Tokenizer; - list<InstrumentData> instruments; - string directory; - void loadLine(const string& line); - -public: - struct InstrumentParam; - - void loadFromList(const string& filename, const vector<string>& list); - StructureDesc getInstrument(mcopbyte channel, mcopbyte note, - mcopbyte velocity, mcopbyte program, - vector<InstrumentParam>*& params); -}; - -struct InstrumentMap::InstrumentParam -{ - string param; - Any value; - - InstrumentParam() - { - } - - InstrumentParam(const InstrumentParam& src) - : param(src.param), value(src.value) - { - } - - InstrumentParam(const string& param, const string& strValue) - : param(param) - { - /* put the string into the any */ - value.type = "string"; - - Buffer b; - b.writeString(strValue); - b.read(value.value, b.size()); - } -}; - -struct InstrumentMap::InstrumentData -{ - struct Range - { - int minValue, maxValue; - Range() : minValue(0), maxValue(0) - { - } - Range(int minValue, int maxValue) - : minValue(minValue), maxValue(maxValue) - { - } - bool match(int value) - { - return (value >= minValue) && (value <= maxValue); - } - }; - Range channel, pitch, program, velocity; - vector<InstrumentParam> params; - StructureDesc instrument; -}; - -class InstrumentMap::Tokenizer { -protected: - bool haveToken, haveNextToken; - string token, nextToken, input; - string::iterator ii; -public: - Tokenizer(const string& line) - : haveToken(false), haveNextToken(false), - input(line+"\n"), ii(input.begin()) - { - /* adding a \n ensures that we will definitely find the last token */ - } - string getToken() - { - if(!haveMore()) - return ""; - - if(haveNextToken) - { - string t = token; - haveNextToken = false; - token = nextToken; - return t; - } - else - { - haveToken = false; - return token; - } - } - bool haveMore() - { - if(haveToken) - return true; - - token = ""; - while(ii != input.end() && !haveToken) - { - const char& c = *ii++; - - if(c == ' ' || c == '\t' || c == '\n') - { - if(!token.empty()) haveToken = true; - } - else if(c == '=') /* || c == '-' || c == '+')*/ - { - if(!token.empty()) - { - haveNextToken = true; - nextToken = c; - } - else - { - token = c; - } - haveToken = true; - } - else - { - token += c; - } - } - return haveToken; - } -}; - -void InstrumentMap::loadLine(const string& line) -{ - Tokenizer t(line); - InstrumentData id; - /* default: no filtering */ - id.channel = InstrumentData::Range(0,15); - id.pitch = id.program = id.velocity = InstrumentData::Range(0,127); - - string s[3]; - int i = 0; - bool seenDo = false; - bool loadOk = false; - - if(t.getToken() != "ON") - { - arts_warning("error in arts-map: lines must start with ON (did start with %s)\n", t.getToken().c_str()); - return; - } - - while(t.haveMore()) - { - const string& token = t.getToken(); - - if(token == "DO") - seenDo = true; - else - { - s[i] = token; - if(i == 2) /* evaluate */ - { - if(s[1] != "=") - { - arts_warning("error in arts-map: no = operator\n"); - return; - } - - if(seenDo) - { - if(s[0] == "structure") - { - string filename = s[2]; - - /* if it's no absolute path, its relative to the map */ - if(!filename.empty() && filename[0] != '/') - filename = directory + "/" + s[2]; - - ifstream infile(filename.c_str()); - string line; - vector<string> strseq; - - while(getline(infile,line)) - strseq.push_back(line); - - id.instrument.loadFromList(strseq); - if(id.instrument.name() != "unknown") - { - loadOk = true; - } - else - { - arts_warning("mapped instrument: " - "can't load structure %s",s[2].c_str()); - } - } - else - { - /* TODO: handle different datatypes */ - id.params.push_back(InstrumentParam(s[0], s[2])); - } - } - else - { - InstrumentData::Range range; - range.minValue = atoi(s[2].c_str()); - range.maxValue = range.minValue; - int i = s[2].find("-",0); - if(i != 0) - { - range.minValue = atoi(s[2].substr(0,i).c_str()); - range.maxValue = - atoi(s[2].substr(i+1,s[2].size()-(i+1)).c_str()); - } - if(s[0] == "pitch") id.pitch = range; - if(s[0] == "channel") id.channel = range; - if(s[0] == "program") id.program = range; - if(s[0] == "velocity") id.velocity = range; - } - i = 0; - } - else i++; - } - } - if(loadOk) instruments.push_back(id); -} - -void InstrumentMap::loadFromList(const string& filename, - const vector<string>& list) -{ - int r = filename.rfind('/'); - if(r > 0) - directory = filename.substr(0,r); - else - directory = ""; - - vector<string>::const_iterator i; - instruments.clear(); - for(i = list.begin(); i != list.end(); i++) loadLine(*i); -} - -StructureDesc InstrumentMap::getInstrument(mcopbyte channel, mcopbyte note, - mcopbyte velocity, mcopbyte program, - vector<InstrumentParam>*& params) -{ - list<InstrumentData>::iterator i; - for(i = instruments.begin(); i != instruments.end(); i++) - { - InstrumentData &id = *i; - - if(id.channel.match(channel) && id.pitch.match(note) && - id.velocity.match(velocity) && id.program.match(program)) - { - params = &id.params; - return id.instrument; - } - } - - return StructureDesc::null(); -} - - -/*-------instrument mapping end -------*/ - -static SynthModule get_AMAN_PLAY(Object structure) -{ - Object resultObj = structure._getChild("play"); - assert(!resultObj.isNull()); - - SynthModule result = DynamicCast(resultObj); - assert(!result.isNull()); - - return result; -} - -struct TSNote { - MidiPort port; - MidiEvent event; - TSNote(MidiPort port, const MidiEvent& event) : - port(port), event(event) - { - } -}; - -class AutoMidiRelease : public TimeNotify { -public: - vector<MidiReleaseHelper> impls; - AutoMidiRelease() - { - Dispatcher::the()->ioManager()->addTimer(10, this); - } - virtual ~AutoMidiRelease() - { - Dispatcher::the()->ioManager()->removeTimer(this); - } - void notifyTime() - { - vector<MidiReleaseHelper>::iterator i = impls.begin(); - while(i != impls.end()) - { - if(i->terminate()) - { - MidiReleaseHelper& helper = *i; - - arts_debug("one voice terminated"); - // put the MidiReleaseHelper and the voice into the ObjectCache - // (instead of simply freeing it) - ObjectCache cache = helper.cache(); - SynthModule voice = helper.voice(); - get_AMAN_PLAY(voice).stop(); - voice.stop(); - cache.put(voice,helper.name()); - impls.erase(i); - return; - } else i++; - } - } -} *autoMidiRelease; - -// cache startup & shutdown -static class AutoMidiReleaseStart :public StartupClass -{ -public: - void startup() { autoMidiRelease = new AutoMidiRelease(); } - void shutdown() { delete autoMidiRelease; } -} autoMidiReleaseStart; - -class MidiReleaseHelper_impl : virtual public MidiReleaseHelper_skel, - virtual public StdSynthModule -{ -protected: - bool _terminate; - SynthModule _voice; - ObjectCache _cache; - string _name; - -public: - MidiReleaseHelper_impl() - { - autoMidiRelease->impls.push_back(MidiReleaseHelper::_from_base(_copy())); - } - ~MidiReleaseHelper_impl() { - artsdebug("MidiReleaseHelper: one voice is gone now\n"); - } - - - SynthModule voice() { return _voice; } - void voice(SynthModule voice) { _voice = voice; } - - ObjectCache cache() { return _cache; } - void cache(ObjectCache cache) { _cache = cache; } - - string name() { return _name; } - void name(const string& name) { _name = name; } - - bool terminate() { return _terminate; } - void streamStart() { _terminate = false; } - - void calculateBlock(unsigned long /*samples*/) - { - if(done[0] > 0.5) - _terminate = true; - } -}; -REGISTER_IMPLEMENTATION(MidiReleaseHelper_impl); - -class Synth_MIDI_TEST_impl : virtual public Synth_MIDI_TEST_skel, - virtual public StdSynthModule { -protected: - struct ChannelData { - SynthModule voice[128]; - string name[128]; - float pitchShiftValue; - mcopbyte program; - ChannelData() { - // initialize all voices with NULL objects (no lazy create) - for(int i = 0; i < 128; i++) voice[i] = SynthModule::null(); - - pitchShiftValue = 0.0; - program = 0; - } - } *channelData; /* data for all 16 midi channels */ - - bool useMap; - InstrumentMap map; - StructureDesc instrument; - StructureBuilder builder; - AudioManagerClient amClient; - ObjectCache cache; - MidiClient client; - MidiTimer timer; - - string _filename; - string _busname; - string _title; -public: - Synth_MIDI_TEST self() { return Synth_MIDI_TEST::_from_base(_copy()); } - - Synth_MIDI_TEST_impl(); - ~Synth_MIDI_TEST_impl(); - - void filename(const string& newname); - string filename() - { - return _filename; - } - void busname(const string& newname); - string busname() - { - return _busname; - } - string title() - { - return _title; - } - void noteOn(mcopbyte channel, mcopbyte note, mcopbyte velocity); - void noteOff(mcopbyte channel, mcopbyte note); - void pitchWheel(mcopbyte channel, mcopbyte lsb, mcopbyte msb); - - float getFrequency(mcopbyte note,mcopbyte channel); - - void streamStart(); - void streamEnd(); - - TimeStamp time() - { - return timer.time(); - } - TimeStamp playTime() - { - /* - * what the user currently hears is exactly latencySec before our - * port timeStamp (as this is the size of the audio buffer) - */ - double latencySec = AudioSubSystem::the()->outputDelay(); - TimeStamp t = time(); - - int sec = int(latencySec); - t.sec -= sec; - latencySec -= double(sec); - t.usec -= int(latencySec * 1000000.0); - - if (t.usec < 0) - { - t.usec += 1000000; - t.sec -= 1; - } - - arts_assert(t.usec >= 0 && t.usec < 1000000); - return t; - } - void processEvent(const MidiEvent& event) - { - timer.queueEvent(self(),event); - } - void processCommand(const MidiCommand& command) - { - mcopbyte channel = command.status & mcsChannelMask; - - switch(command.status & mcsCommandMask) - { - case mcsNoteOn: noteOn(channel,command.data1,command.data2); - return; - case mcsNoteOff: noteOff(channel,command.data1); - return; - case mcsPitchWheel: pitchWheel(channel,command.data1,command.data2); - return; - case mcsProgram: channelData[channel].program = command.data1; - return; - case mcsParameter: - if(command.data1 == mcpAllNotesOff && command.data2 == 0) - for(mcopbyte note=0; note<128; note++) - noteOff(channel,note); - return; - } - } -}; -REGISTER_IMPLEMENTATION(Synth_MIDI_TEST_impl); - - -void Synth_MIDI_TEST_impl::busname(const string& newname) -{ - // TODO: - _busname = newname; -} - -void Synth_MIDI_TEST_impl::filename(const string& newname) -{ - ifstream infile(newname.c_str()); - string line; - vector<string> strseq; - - while(getline(infile,line)) - strseq.push_back(line); - - _filename = newname; - -/* search extension */ - string::const_reverse_iterator i; - string extension; - bool extensionok = false; - - for(i = newname.rbegin(); i != newname.rend() && !extensionok; i++) - { - if(*i == '.') - extensionok = true; - else - extension.insert(extension.begin(), (char)tolower(*i)); - } - - if(extensionok && extension == "arts") - { - instrument.loadFromList(strseq); - _title = "aRts Instrument ("+instrument.name()+")"; - useMap = false; - } - else if(extensionok && extension == "arts-map") - { - map.loadFromList(newname, strseq); - _title = "aRts Instrument (mapped)"; - useMap = true; - } - - if(!client.isNull()) - client.title(title()); - amClient.title(title()); -} - -Synth_MIDI_TEST_impl::Synth_MIDI_TEST_impl() - : amClient(amPlay, "aRts Instrument","Synth_MIDI_TEST") -{ - useMap = false; - client = MidiClient::null(); - timer = SubClass("Arts::AudioMidiTimer"); - channelData = new ChannelData[16]; -} - -Synth_MIDI_TEST_impl::~Synth_MIDI_TEST_impl() -{ - delete[] channelData; -} - -void Synth_MIDI_TEST_impl::streamStart() -{ - // register with the midi manager - MidiManager manager = Reference("global:Arts_MidiManager"); - if(!manager.isNull()) - { - client = manager.addClient(mcdRecord,mctDestination,title(), - "Arts::Synth_MIDI_TEST"); - client.addInputPort(self()); - } - else - arts_warning("Synth_MIDI_TEST: no midi manager found - not registered"); -} - -void Synth_MIDI_TEST_impl::streamEnd() -{ - client = MidiClient::null(); -} - -void Synth_MIDI_TEST_impl::noteOn(mcopbyte channel, mcopbyte note, - mcopbyte velocity) -{ - if(velocity == 0) - { - noteOff(channel,note); - return; - } - if(!channelData[channel].voice[note].isNull()) - { - noteOff(channel,note); - arts_info("Synth_MIDI_TEST: duplicate noteOn (mixed channels?)"); - } - - vector<InstrumentMap::InstrumentParam> *params = 0; - if(useMap) - { - mcopbyte program = channelData[channel].program; - StructureDesc sd = map.getInstrument(channel,note,velocity,program,params); - if(sd.isNull()) return; - instrument = sd; - } - - Object structureObject = cache.get(instrument.name()); - if(structureObject.isNull()) - { - arts_debug("creating new structure"); - structureObject = builder.createObject(instrument); - - SynthModule play; - // TODO: allow changing busname! - if(!_busname.empty()) - { - Synth_BUS_UPLINK b; - b.busname(_busname); - play = b; - } - else - { - Synth_AMAN_PLAY a(amClient); - play = a; - } - structureObject._addChild(play,"play"); - connect(structureObject,"left",play,"left"); - connect(structureObject,"right",play,"right"); - } - else - { - arts_debug("used cached structure"); - } - - SynthModule structure = DynamicCast(structureObject); - assert(!structure.isNull()); - - if(params) - { - vector<InstrumentMap::InstrumentParam>::iterator pi; - for(pi = params->begin(); pi != params->end(); pi++) - { - DynamicRequest req(structure); - - req.method("_set_"+pi->param).param(pi->value).invoke(); - } - } - setValue(structure,"frequency",getFrequency(note,channel)); - setValue(structure,"velocity",(float)velocity/127.0); - setValue(structure,"pressed",1.0); - - get_AMAN_PLAY(structure).start(); - structure.start(); - - channelData[channel].voice[note] = structure; - channelData[channel].name[note] = instrument.name(); -} - -void Synth_MIDI_TEST_impl::noteOff(mcopbyte channel, mcopbyte note) -{ - if(!channelData[channel].voice[note].isNull()) - { - setValue(channelData[channel].voice[note],"pressed",0.0); - - MidiReleaseHelper h; - - h.voice(channelData[channel].voice[note]); - h.cache(cache); - h.name(channelData[channel].name[note]); - - connect(channelData[channel].voice[note],"done",h,"done"); - h.start(); - assert(!h.terminate()); - channelData[channel].voice[note] = SynthModule::null(); - } -} - -float Synth_MIDI_TEST_impl::getFrequency(mcopbyte note, mcopbyte channel) -{ - /* 2 semitones pitchshift */ - return 261.63 * pow(2,((float)(note)+(channelData[channel].pitchShiftValue*2.0))/12.0)/32.0; -} - -void Synth_MIDI_TEST_impl::pitchWheel(mcopbyte channel, - mcopbyte lsb, mcopbyte msb) -{ - mcopbyte note; - - channelData[channel].pitchShiftValue = - (float)((lsb + msb*128) - (0x40*128))/8192.0; - - for(note = 0; note < 128; note++) - { - if(!channelData[channel].voice[note].isNull()) - setValue(channelData[channel].voice[note],"frequency",getFrequency(note,channel)); - } -} |