Skip to content

Commit

Permalink
Note expressions via OSC: fully functional
Browse files Browse the repository at this point in the history
  • Loading branch information
pkstone authored and baconpaul committed Aug 31, 2023
1 parent f9ed0b4 commit d536e6e
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 46 deletions.
8 changes: 6 additions & 2 deletions src/surge-xt/SurgeSynthProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -693,24 +693,28 @@ void SurgeSynthProcessor::processBlockOSC()
pval = Parameter::intScaledToFloat(pval, om.param->val_max.i, om.param->val_min.i);
surge->setParameter01(surge->idForParameter(om.param), pval, true);
surge->storage.getPatch().isDirty = true;
break;
}
break;

case SurgeSynthProcessor::MNOTE:
{
if (om.on)
surge->playNote(0, om.mnote, om.vel, 0, om.mnote);
else
surge->releaseNote(0, om.mnote, om.vel, om.mnote);
}
break;

case SurgeSynthProcessor::FREQNOTE:
{
if (om.on)
surge->playNoteByFrequency(om.fval, om.vel, om.noteid);
else
{
// auto k = 12 * log2(om.fval / 440) + 69;
surge->releaseNoteByHostNoteID(om.vel, om.noteid);
surge->releaseNoteByHostNoteID(om.noteid, om.vel);
}
}
break;

default:
Expand Down
32 changes: 16 additions & 16 deletions src/surge-xt/gui/SurgeGUIEditorHtmlGenerators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ code {
<div class="tablewrap" style="width: 1100px; margin: 8px auto;">
<div class="heading">
<h3>Note Expressions (in progress):</h3>
<h3>Note Expressions:</h3>
</div>
<table style="border: 2px solid black;">
<tr>
Expand All @@ -720,34 +720,34 @@ code {
<th>Arg. 2</th>
</tr>
<tr>
<td><b>† </b>/nex/pitch</td>
<td><b>† </b>/ne/pitch</td>
<td>pitch note expression</td>
<td>pitch offset (0 - 127)</td>
<td>noteID (0 - maxint)§
<td>pitch offset (-120.0 - 120.0:&nbsp;&nbsp;semitones)</td>
</tr>
<tr>
<td><b>† </b>/nex/vol</td>
<td><b>† </b>/ne/volume</td>
<td>volume note expression</td>
<td>volume offset (0 - 127)</td>
<td>noteID (0 - maxint)§
<td>volume multiplier (0.0 - 4.0)</td>
</tr>
<tr>
<td><b>† </b>/nex/pan</td>
<td><b>† </b>/ne/pan</td>
<td>pan note expression</td>
<td>position (0 - 127)</td>
<td>noteID (0 - maxint)§
<td>position (0.0 - 1.0:&nbsp;&nbsp;0.0=left&nbsp;&nbsp;0.5=center&nbsp;&nbsp;1.0=right)</td>
</tr>
<tr>
<td><b>† </b>/nex/timb</td>
<td><b>† </b>/ne/timbre</td>
<td>timbre note expression</td>
<td>timbre (0 - 127)</td>
<td>noteID (0 - maxint)§
<td>timbre (0.0 - 1.0:&nbsp;&nbsp;'brightness')</td>
</tr>
<tr>
<td><b>† </b>/nex/press</td>
<td><b>† </b>/ne/pressure</td>
<td>pressure note expression</td>
<td>pressure(0 - 127)</td>
<td>noteID (0 - maxint)§
<td>pressure (0.0 - 1.0)</td>
</tr>
<tr>
<td colspan="5">
Expand All @@ -757,11 +757,11 @@ code {
</table>
</div>
<div style="width: 1100px; margin: 8px auto; line-height: 1.75">
<span><code>/nex/pitch 0.34 24566</code></span>
<span><code>/nex/vol 0.5 24566</code></span>
<span><code>/nex/pan 0.9 24566</code></span>
<span><code>/nex/timb 0.18 24566</code></span>
<span><code>/nex/press 0.4 24566</code></span>
<span><code>/ne/pitch 24566 0.34</code></span>
<span><code>/ne/volume 24566 0.5</code></span>
<span><code>/ne/pan 24566 0.9</code></span>
<span><code>/ne/timbre 24566 0.18</code></span>
<span><code>/ne/pressure 24566 0.4</code></span>
</div>
<div class="tablewrap fl cl">
Expand Down
95 changes: 68 additions & 27 deletions src/surge-xt/osc/OpenSoundControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,16 @@ std::string OpenSoundControl::getWholeString(const juce::OSCMessage &om)
return dataStr;
}

int OpenSoundControl::getNoteID(const juce::OSCMessage &om)
int OpenSoundControl::getNoteID(const juce::OSCMessage &om, int pos)
{
// note id supplied by sender
{
if (!om[2].isFloat32())
if (!om[pos].isFloat32())
{
sendNotFloatError("fnote", "noteID");
sendNotFloatError("fnote or note expression", "noteID");
return -1;
}
float msg2 = om[2].getFloat32();
float msg2 = om[pos].getFloat32();
if (msg2 < 0. || msg2 > (float)(std::numeric_limits<int>::max()))
{
sendError("NoteID must be between 0 and " +
Expand Down Expand Up @@ -138,36 +138,85 @@ void OpenSoundControl::oscMessageReceived(const juce::OSCMessage &message)
std::string address1, address2, address3;
std::getline(split, address1, '/');

if (address1 == "nex")
// Note expressions
if (address1 == "ne")
{
if (message.size() != 1)
if (message.size() != 2)
{
sendDataCountError("note expression", "1");
sendDataCountError("note expression", "2");
}
if (!message[0].isFloat32())
{
sendNotFloatError("ne", "value");
return;
}
int noteID = getNoteID(message, 0);
if (noteID == -1)
{
sendError("Note expressions require a valid noteID.");
return;
}
float val = message[1].getFloat32();

int id = 444; // change this
float val = 0.0;
std::getline(split, address2, '/');
if (address2 == "vol")
if (address2 == "volume")
{
// sspPtr->oscRingBuf.push();
if (val < 0.0 || val > 4.0)
{
sendError("Note expression (volume) '" + std::to_string(val) +
"' is out of range (0.0 - 4.0).");
return;
}
sspPtr->oscRingBuf.push(
SurgeSynthProcessor::oscToAudio(SurgeSynthProcessor::NOTEX_VOL, noteID, val));
}
else if (address2 == "pitch")
{
float offset = 0.0; // PKS TODO:change this
if (val < -120.0 || val > 120.0)
{
sendError("Note expression (pitch) '" + std::to_string(val) +
"' is out of range (-120.0 - 120.0).");
return;
}
sspPtr->oscRingBuf.push(
SurgeSynthProcessor::oscToAudio(SurgeSynthProcessor::NOTEX_PITCH, id, offset));
SurgeSynthProcessor::oscToAudio(SurgeSynthProcessor::NOTEX_PITCH, noteID, val));
}
else if (address2 == "pan")
{
if (val < 0.0 || val > 1.0)
{
sendError("Note expression (pan) '" + std::to_string(val) +
"' is out of range (0.0 - 1.0).");
return;
}
sspPtr->oscRingBuf.push(
SurgeSynthProcessor::oscToAudio(SurgeSynthProcessor::NOTEX_PAN, noteID, val));
}
else if (address2 == "timb")
else if (address2 == "timbre")
{
if (val < 0.0 || val > 1.0)
{
sendError("Note expression (timbre) '" + std::to_string(val) +
"' is out of range (0.0 - 1.0).");
return;
}
sspPtr->oscRingBuf.push(
SurgeSynthProcessor::oscToAudio(SurgeSynthProcessor::NOTEX_TIMB, noteID, val));
}
else if (address2 == "press")
else if (address2 == "pressure")
{
if (val < 0.0 || val > 1.0)
{
sendError("Note expression (pressure) '" + std::to_string(val) +
"' is out of range (0.0 - 1.0).");
return;
}
sspPtr->oscRingBuf.push(
SurgeSynthProcessor::oscToAudio(SurgeSynthProcessor::NOTEX_PRES, noteID, val));
}
}

// 'Frequency' notes
else if (address1 == "fnote")
// Play a note at the given frequency and velocity
{
Expand All @@ -191,20 +240,10 @@ void OpenSoundControl::oscMessageReceived(const juce::OSCMessage &message)
}
if (message.size() == 3)
{
noteID = getNoteID(message);
noteID = getNoteID(message, 2);
if (noteID == -1)
return;
}
if (message.size() == 3)
// note id supplied
{
if (!message[2].isFloat32())
{
sendNotFloatError("fnote", "noteID");
return;
}
noteID = static_cast<int>(message[2].getFloat32());
}

float frequency = message[0].getFloat32();
int velocity = static_cast<int>(message[1].getFloat32());
Expand Down Expand Up @@ -235,6 +274,7 @@ void OpenSoundControl::oscMessageReceived(const juce::OSCMessage &message)
frequency, static_cast<char>(velocity), noteon, noteID));
}

// "MIDI-style" notes
else if (address1 == "mnote")
// OSC equivalent of MIDI note
{
Expand All @@ -257,7 +297,7 @@ void OpenSoundControl::oscMessageReceived(const juce::OSCMessage &message)

if (message.size() == 3)
{
noteID = getNoteID(message);
noteID = getNoteID(message, 2);
if (noteID == -1)
return;
}
Expand Down Expand Up @@ -286,6 +326,7 @@ void OpenSoundControl::oscMessageReceived(const juce::OSCMessage &message)
static_cast<char>(note), static_cast<char>(velocity), noteon, noteID));
}

// Parameters
else if (address1 == "param")
{
if (message.size() != 1)
Expand Down
2 changes: 1 addition & 1 deletion src/surge-xt/osc/OpenSoundControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class OpenSoundControl : public juce::OSCReceiver,
SurgeSynthesizer *synth{nullptr};
SurgeSynthProcessor *sspPtr{nullptr};
std::string getWholeString(const juce::OSCMessage &message);
int getNoteID(const juce::OSCMessage &om);
int getNoteID(const juce::OSCMessage &om, int pos);
juce::OSCSender juceOSCSender;
void sendError(std::string errorMsg);
void sendNotFloatError(std::string addr, std::string msg);
Expand Down

0 comments on commit d536e6e

Please sign in to comment.