Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 71 additions & 5 deletions patch/Nimbus/Nimbus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ using namespace daisy;

GranularProcessorClouds processor;
DaisyPatch hw;
MidiHandler midi;

// Pre-allocate big blocks in main memory and CCM. No malloc here.
uint8_t block_mem[118784];
Expand All @@ -17,6 +18,7 @@ uint8_t block_ccm[65536 - 128];
char paramNames[NUM_PARAMS][17];
char pbModeNames[4][17];
char qualityNames[4][17];
char channelName[32];

int mymod(int a, int b)
{
Expand All @@ -43,7 +45,7 @@ class ParamControl
param_num_ = mymod(param_num_, NUM_PARAMS);
}

char* getName() { return paramNames[param_num_]; }
char* getName(int inc = 0) { return paramNames[mymod(param_num_ + inc, NUM_PARAMS)]; }

bool knobTouched(float newval)
{
Expand Down Expand Up @@ -93,6 +95,8 @@ bool held;
bool freeze_btn;
int pbMode;
int quality;
int increment;
int channel;

Parameters* parameters;

Expand Down Expand Up @@ -147,12 +151,53 @@ void InitStrings()
sprintf(qualityNames[3], "8 bit ulaw mono");
}

void HandleMidiMessage(MidiEvent m, int channel, Parameters* params)
{
if(m.channel == channel)
{
switch(m.type)
{
case NoteOn:
{
NoteOnEvent p = m.AsNoteOn();
// This is to avoid Max/MSP Note outs for now..
if(m.data[1] != 0)
{
p = m.AsNoteOn();
params->pitch = p.note - 64.0f;
}
}
break;
case ControlChange:
{
ControlChangeEvent p = m.AsControlChange();
switch(p.control_number)
{
case 1: params->position = p.value/127.f; break;
case 2: params->size = p.value/127.f; break;
case 3: params->density = p.value/127.f; break;
case 4: params->texture = p.value/127.f; break;
case 5: params->dry_wet = p.value/127.f; break;
case 6: params->stereo_spread = p.value/127.f; break;
case 7: params->feedback = p.value/127.f; break;
case 8: params->reverb = p.value/127.f; break;
default: break;
}
break;
}
default: break;
}
}
}

int main(void)
{
hw.Init();
hw.SetAudioBlockSize(32); // clouds won't work with blocks bigger than 32
float sample_rate = hw.AudioSampleRate();

midi.Init(MidiHandler::INPUT_MODE_UART1, MidiHandler::OUTPUT_MODE_NONE);

//init the luts
InitResources(sample_rate);

Expand Down Expand Up @@ -180,13 +225,22 @@ int main(void)
held = false;
freeze_btn = false;
menupage = 0;
increment = 0;

hw.StartAdc();
hw.StartAudio(AudioCallback);
midi.StartReceive();
while(1)
{
processor.Prepare();

midi.Listen();
// Handle MIDI Events
while(midi.HasEvents())
{
HandleMidiMessage(midi.PopEvent(), channel, parameters);
}

hw.display.Fill(false);
hw.display.DrawLine(0, 10, 128, 10, true);

Expand All @@ -204,7 +258,7 @@ int main(void)
{
hw.display.SetCursor(10, i * 13 + 13);
hw.display.WriteString(
paramControls[i].getName(), Font_7x10, true);
paramControls[i].getName((i == cursorpos) ? increment : 0), Font_7x10, !(selected && (i == cursorpos)));
};
break;
case 1:
Expand All @@ -220,6 +274,10 @@ int main(void)

hw.display.SetCursor(10, 2 * 13 + 13);
hw.display.WriteString(qualityNames[quality], Font_7x10, true);

hw.display.SetCursor(10, 3 * 13 + 13);
sprintf(channelName, "Midi channel: %d", channel+1);
hw.display.WriteString(channelName, Font_7x10, true);
break;
}

Expand Down Expand Up @@ -251,7 +309,7 @@ void Controls()
{
if(menupage == 0)
{
paramControls[cursorpos].incParamNum(hw.encoder.Increment());
increment += hw.encoder.Increment();
}
else
{
Expand All @@ -268,17 +326,25 @@ void Controls()
quality = mymod(quality, 4);
processor.set_quality(quality);
break;
case 3:
channel += hw.encoder.Increment();
channel = mymod(channel, 16);
break;
}
}
}
else
{
if (increment != 0){
paramControls[cursorpos].incParamNum(increment);
increment = 0;
}
cursorpos += hw.encoder.Increment();
cursorpos = mymod(cursorpos, menupage ? 3 : 4);
cursorpos = mymod(cursorpos, 4);
}

// gate ins
parameters->freeze = hw.gate_input[0].State() || freeze_btn;
parameters->trigger = hw.gate_input[1].Trig();
parameters->gate = hw.gate_input[1].State();
}
}
20 changes: 19 additions & 1 deletion patch/Nimbus/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,22 @@ You can also select from four quality / mono stereo modes. These are:
- 16 bit Mono
- 8bit u-law Stereo
- 8bit u-law Mono
Refer to the [Clouds Manual](https://mutable-instruments.net/modules/clouds/manual/) section on "Audio Quality".
Refer to the [Clouds Manual](https://mutable-instruments.net/modules/clouds/manual/) section on "Audio Quality".

#### Midi Channel
In this Menu you can configure which midi channel Nimbus should listen to.

You can control all paramters via Midi:
- NoteOn events set the pitch parameter.
- All other parameters can be adjusted using midi ControlChange messages.

| CC# | parameter |
| --- | ------------- |
| CC1 | position |
| CC2 | size |
| CC3 | density |
| CC4 | texture |
| CC5 | dry_wet |
| CC6 | stereo_spread |
| CC7 | feedback |
| CC8 | reverb |