Skip to content

Commit

Permalink
midi in & out
Browse files Browse the repository at this point in the history
  • Loading branch information
pierreguillot committed Mar 17, 2016
1 parent 8a5f7fd commit 9a54b31
Show file tree
Hide file tree
Showing 9 changed files with 299 additions and 136 deletions.
12 changes: 0 additions & 12 deletions Builds/LinuxMakefile/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,6 @@ OBJECTS := \
$(OBJDIR)/s_inter_106fd5bd.o \
$(OBJDIR)/s_loader_499588dc.o \
$(OBJDIR)/s_main_b40a6202.o \
$(OBJDIR)/s_midi_b478c56a.o \
$(OBJDIR)/s_midi_dummy_723fbb13.o \
$(OBJDIR)/s_path_b92dd56e.o \
$(OBJDIR)/s_print_88f7f34e.o \
$(OBJDIR)/s_utf8_c2babdba.o \
Expand Down Expand Up @@ -601,16 +599,6 @@ $(OBJDIR)/s_main_b40a6202.o: ../../ThirdParty/PureData/src/s_main.c
@echo "Compiling s_main.c"
@$(CC) $(CFLAGS) -o "$@" -c "$<"

$(OBJDIR)/s_midi_b478c56a.o: ../../ThirdParty/PureData/src/s_midi.c
-@mkdir -p $(OBJDIR)
@echo "Compiling s_midi.c"
@$(CC) $(CFLAGS) -o "$@" -c "$<"

$(OBJDIR)/s_midi_dummy_723fbb13.o: ../../ThirdParty/PureData/src/s_midi_dummy.c
-@mkdir -p $(OBJDIR)
@echo "Compiling s_midi_dummy.c"
@$(CC) $(CFLAGS) -o "$@" -c "$<"

$(OBJDIR)/s_path_b92dd56e.o: ../../ThirdParty/PureData/src/s_path.c
-@mkdir -p $(OBJDIR)
@echo "Compiling s_path.c"
Expand Down
2 changes: 0 additions & 2 deletions Builds/VisualStudio2015/Camomile.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,6 @@
<ClCompile Include="..\..\ThirdParty\PureData\src\s_inter.c"/>
<ClCompile Include="..\..\ThirdParty\PureData\src\s_loader.c"/>
<ClCompile Include="..\..\ThirdParty\PureData\src\s_main.c"/>
<ClCompile Include="..\..\ThirdParty\PureData\src\s_midi.c"/>
<ClCompile Include="..\..\ThirdParty\PureData\src\s_midi_dummy.c"/>
<ClCompile Include="..\..\ThirdParty\PureData\src\s_path.c"/>
<ClCompile Include="..\..\ThirdParty\PureData\src\s_print.c"/>
<ClCompile Include="..\..\ThirdParty\PureData\src\s_utf8.c"/>
Expand Down
6 changes: 0 additions & 6 deletions Builds/VisualStudio2015/Camomile.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -523,12 +523,6 @@
<ClCompile Include="..\..\ThirdParty\PureData\src\s_main.c">
<Filter>Camomile\PureData\src</Filter>
</ClCompile>
<ClCompile Include="..\..\ThirdParty\PureData\src\s_midi.c">
<Filter>Camomile\PureData\src</Filter>
</ClCompile>
<ClCompile Include="..\..\ThirdParty\PureData\src\s_midi_dummy.c">
<Filter>Camomile\PureData\src</Filter>
</ClCompile>
<ClCompile Include="..\..\ThirdParty\PureData\src\s_path.c">
<Filter>Camomile\PureData\src</Filter>
</ClCompile>
Expand Down
2 changes: 0 additions & 2 deletions Camomile.jucer
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,6 @@
<FILE id="EQZawY" name="s_inter.c" compile="1" resource="0" file="ThirdParty/PureData/src/s_inter.c"/>
<FILE id="WsEHMF" name="s_loader.c" compile="1" resource="0" file="ThirdParty/PureData/src/s_loader.c"/>
<FILE id="Ic6LsD" name="s_main.c" compile="1" resource="0" file="ThirdParty/PureData/src/s_main.c"/>
<FILE id="VtfePp" name="s_midi.c" compile="1" resource="0" file="ThirdParty/PureData/src/s_midi.c"/>
<FILE id="EFaawO" name="s_midi_dummy.c" compile="1" resource="0" file="ThirdParty/PureData/src/s_midi_dummy.c"/>
<FILE id="CfZaK0" name="s_path.c" compile="1" resource="0" file="ThirdParty/PureData/src/s_path.c"/>
<FILE id="PvtjZi" name="s_print.c" compile="1" resource="0" file="ThirdParty/PureData/src/s_print.c"/>
<FILE id="vIreZA" name="s_stuff.h" compile="0" resource="0" file="ThirdParty/PureData/src/s_stuff.h"/>
Expand Down
87 changes: 64 additions & 23 deletions Source/InstanceProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,40 +212,81 @@ void InstanceProcessor::processBlock(AudioSampleBuffer& buffer, MidiBuffer& midi
buffer.clear(i, 0, buffer.getNumSamples());
}

MidiMessage message;
MidiBuffer::Iterator it(midiMessages);
int samplePosition = buffer.getNumSamples();

lock();
while(it.getNextEvent(message, samplePosition))
{
if(message.isNoteOnOrOff())
{
sendNote(message.getChannel(), message.getNoteNumber(), message.getVelocity());
}
else if(message.isController())
{
sendControlChange(message.getChannel(), message.getControllerNumber(), message.getControllerValue());
}
else if(message.isPitchWheel())
MidiMessage message;
MidiBuffer::Iterator it(midiMessages);
int position = buffer.getNumSamples();
while(it.getNextEvent(message, position))
{
sendPitchBend(message.getChannel(), message.getPitchWheelValue());
}
else if(message.isAftertouch())
{
sendAfterTouch(message.getChannel(), message.getAfterTouchValue());
}
else if(message.isProgramChange())
{
sendProgramChange(message.getChannel(), message.getProgramChangeNumber());
if(message.isNoteOnOrOff())
{
pd::Pd::sendNote(message.getChannel(), message.getNoteNumber(), message.getVelocity());
}
else if(message.isController())
{
pd::Pd::sendControlChange(message.getChannel(), message.getControllerNumber(), message.getControllerValue());
}
else if(message.isPitchWheel())
{
pd::Pd::sendPitchBend(message.getChannel(), message.getPitchWheelValue());
}
else if(message.isChannelPressure())
{
pd::Pd::sendAfterTouch(message.getChannel(), message.getChannelPressureValue());
}
else if(message.isAftertouch())
{
pd::Pd::sendPolyAfterTouch(message.getChannel(), message.getNoteNumber(), message.getAfterTouchValue());
}
else if(message.isProgramChange())
{
pd::Pd::sendProgramChange(message.getChannel(), message.getProgramChangeNumber());
}
}
}

midiMessages.clear();
for(size_t i = 0; i < m_parameters.size() && m_parameters[i].isValid(); ++i)
{
send(m_parameters[i].getBindingName(), m_parameters[i].getValueNonNormalized());
}

//midiMessages.addEvent(
{
const int position = buffer.getNumSamples();
pd::MidiList::const_iterator it = pd::Pd::getMidiBegin();
while(it != pd::Pd::getMidiEnd())
{
if(it->isNoteOn())
{
midiMessages.addEvent(MidiMessage::noteOn(it->getChannel(), it->getPitch(), it->getVelocity()), position);
}
else if(it->isNoteOff())
{
midiMessages.addEvent(MidiMessage::noteOff(it->getChannel(), it->getPitch(), it->getVelocity()), position);
}
else if(it->isControlChange())
{
midiMessages.addEvent(MidiMessage::controllerEvent(it->getChannel(), it->getController(), it->getControl()), position);
}
else if(it->isPitchBend())
{
midiMessages.addEvent(MidiMessage::pitchWheel(it->getChannel(), it->getPitch()), position);
}
else if(it->isAfterTouch())
{
midiMessages.addEvent(MidiMessage::channelPressureChange(it->getChannel(), it->getAfterTouch()), position);
}
else if(it->isPolyafterTouch())
{
midiMessages.addEvent(MidiMessage::aftertouchChange(it->getChannel(), it->getPitch(), it->getAfterTouch()), position);
}
++it;
}
pd::Pd::clearMidi();
}

performDsp(buffer.getNumSamples(),
getTotalNumInputChannels(), buffer.getArrayOfReadPointers(),
getTotalNumOutputChannels(), buffer.getArrayOfWritePointers());
Expand Down
145 changes: 144 additions & 1 deletion Source/Pd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "PdInstance.hpp"
#include <signal.h>

static std::vector<pd::MidiEvent> midiout;

extern "C"
{
#include "../ThirdParty/PureData/src/m_pd.h"
Expand All @@ -26,6 +28,21 @@ void lrshift_tilde_setup();
void pique_setup();
void sigmund_tilde_setup();
void stdout_setup();

void sys_get_midi_apis(char *buf) {}
void sys_listmididevs(void) {}
void sys_get_midi_params(int *pnmidiindev, int *pmidiindev,int *pnmidioutdev, int *pmidioutdev) {}
void sys_open_midi(int nmidiindev, int *midiindev, int nmidioutdev, int *midioutdev, int enable) {}
void sys_close_midi() {}
void sys_reopen_midi(void) {}
void sys_initmidiqueue(void) {}
void sys_pollmidiqueue(void) {}
void sys_setmiditimediff(double inbuftime, double outbuftime) {}
void glob_midi_setapi(void *dummy, t_floatarg f) {}
void glob_midi_properties(t_pd *dummy, t_floatarg flongform) {}
void glob_midi_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv) {}
int sys_mididevnametonumber(int output, const char *name) { return 0; }
void sys_mididevnumbertoname(int output, int devno, char *name, int namesize) {}
}

namespace pd
Expand Down Expand Up @@ -69,7 +86,8 @@ namespace pd
sched_set_using_audio(SCHED_AUDIO_CALLBACK);
sys_reopen_audio();
m_sample_ins = sys_soundin;
m_sample_outs = sys_soundout;
m_sample_outs = sys_soundout;
midiout.reserve(1024);
sys_soundin = nullptr;
sys_soundout = nullptr;
}
Expand Down Expand Up @@ -230,6 +248,131 @@ namespace pd
std::lock_guard<std::mutex> guard(pd.m_mutex);
pdinstance_free(reinterpret_cast<t_pdinstance *>(instance.m_ptr));
}

// From libPD
#define CHECK_CHANNEL if (channel < 0) return;
#define CHECK_PORT if (port < 0 || port > 0x0fff) return;
#define CHECK_RANGE_7BIT(v) if (v < 0 || v > 0x7f) return;
#define CHECK_RANGE_8BIT(v) if (v < 0 || v > 0xff) return;
#define MIDI_PORT (channel >> 4)
#define MIDI_CHANNEL (channel & 0x0f)

void Pd::sendNote(int channel, int pitch, int velocity) {
CHECK_CHANNEL
CHECK_RANGE_7BIT(pitch)
CHECK_RANGE_7BIT(velocity)
inmidi_noteon(MIDI_PORT, MIDI_CHANNEL, pitch, velocity);
}

void Pd::sendControlChange(int channel, int controller, int value) {
CHECK_CHANNEL
CHECK_RANGE_7BIT(controller)
CHECK_RANGE_7BIT(value)
inmidi_controlchange(MIDI_PORT, MIDI_CHANNEL, controller, value);
}

void Pd::sendProgramChange(int channel, int value) {
CHECK_CHANNEL
CHECK_RANGE_7BIT(value)
inmidi_programchange(MIDI_PORT, MIDI_CHANNEL, value);
}

void Pd::sendPitchBend(int channel, int value) {
CHECK_CHANNEL
if (value < -8192 || value > 8191) return;
inmidi_pitchbend(MIDI_PORT, MIDI_CHANNEL, value + 8192);
}

void Pd::sendAfterTouch(int channel, int value) {
CHECK_CHANNEL
CHECK_RANGE_7BIT(value)
inmidi_aftertouch(MIDI_PORT, MIDI_CHANNEL, value);
}

void Pd::sendPolyAfterTouch(int channel, int pitch, int value) {
CHECK_CHANNEL
CHECK_RANGE_7BIT(pitch)
CHECK_RANGE_7BIT(value)
inmidi_polyaftertouch(MIDI_PORT, MIDI_CHANNEL, pitch, value);
}

void Pd::sendMidiByte(int port, int byte) {
CHECK_PORT
CHECK_RANGE_8BIT(byte)
inmidi_byte(port, byte);
}

void Pd::sendSysEx(int port, int byte) {
CHECK_PORT
CHECK_RANGE_7BIT(byte)
inmidi_sysex(port, byte);
}

void Pd::sendSysRealtime(int port, int byte) {
CHECK_PORT
CHECK_RANGE_8BIT(byte)
inmidi_realtimein(port, byte);
}

#undef CHECK_CHANNEL
#undef MIDI_PORT
#undef MIDI_CHANNEL
#undef CHECK_PORT
#undef CHECK_RANGE_7BIT
#undef CHECK_RANGE_8BIT

void Pd::clearMidi()
{
midiout.clear();
}

std::vector<MidiEvent>::const_iterator Pd::getMidiBegin()
{
return midiout.cbegin();
}

std::vector<MidiEvent>::const_iterator Pd::getMidiEnd()
{
return midiout.cend();
}
}

extern "C"
{
void outmidi_noteon(int port, int channel, int pitch, int velo)
{
midiout.push_back(pd::MidiEvent::Note(static_cast<unsigned char>(channel),static_cast<unsigned char>(pitch),static_cast<unsigned char>(velo)));
}

void outmidi_controlchange(int port, int channel, int ctl, int value)
{
midiout.push_back(pd::MidiEvent::ControlChange(static_cast<unsigned char>(channel),static_cast<unsigned char>(ctl),static_cast<unsigned char>(value)));
}

void outmidi_programchange(int port, int channel, int value)
{
midiout.push_back(pd::MidiEvent::ProgramChange(static_cast<unsigned char>(channel),static_cast<unsigned char>(value)));
}

void outmidi_pitchbend(int port, int channel, int value)
{
midiout.push_back(pd::MidiEvent::PitchBend(static_cast<unsigned char>(channel),value));
}

void outmidi_aftertouch(int port, int channel, int value)
{
midiout.push_back(pd::MidiEvent::AfterTouch(static_cast<unsigned char>(channel),static_cast<unsigned char>(value)));
}

void outmidi_polyaftertouch(int port, int channel, int pitch, int value)
{
midiout.push_back(pd::MidiEvent::PolyafterTouch(static_cast<unsigned char>(channel),static_cast<unsigned char>(pitch),static_cast<unsigned char>(value)));
}

void outmidi_byte(int port, int value)
{
midiout.push_back(pd::MidiEvent::Byte(static_cast<unsigned char>(port),static_cast<unsigned char>(value)));
}
}


Expand Down

0 comments on commit 9a54b31

Please sign in to comment.