Stopping a Web Audio oscillator at cycle completion (or zero-crossing)

When calling osc.stop(), a running oscillator is stopped immediately, which can result in a nasty click. This is because the oscillator is stopped right in the middle of a cycle.

Here’s a nice tutorial on how to get rid of the click, using automation curves for smooth gain fade-outs: http://alemangui.github.io/blog//2015/12/26/ramp-to-value.html

But there’s another way: When stopping the oscillator, we could just wait for cycle completion before actually stopping it.

Continue reading “Stopping a Web Audio oscillator at cycle completion (or zero-crossing)”

A piano sustain pedal to MIDI USB adapter

I like my MIDI USB keyboard. But unfortunately, it does not have a sustain pedal jack. That is why I built an adapter, which translates the pedal input into MIDI messages.

All it took was an Arduino Leonardo (Pro Micro module with ATmega32U4), a breadboard, a 7-segment LED display, two resistors, 2 toothsticks, a 6,3mm mono jack socket and some jumper wires. The LED display with its two resistors are optional, of course.

Arduino Code


#include "MIDIUSB.h"

bool isPedalPressed = false;
int pedalPin = 3;

void setup() {
	pinMode(pedalPin, INPUT);

	// turn on pullup resistor as described in http://electronics.stackexchange.com/questions/83133/arduino-digitalread-reading-wrong
	digitalWrite(pedalPin, HIGH);
	
}


void loop() {
	//Pedal pin is by default HIGH, because of pullup resistor
	//When pedal is pushed down, pin should be connected with GND, so that it gets LOW

    if ((digitalRead(pedalPin) == LOW) && (isPedalPressed == false)){

        //channel 1, CC 64 (Sustain), Value 127
        controlChange(0x00, 0x40, 0x7F);
        MidiUSB.flush();
        isPedalPressed = true;
        ledDisplayOne();  //optional
        return;

    }
    
    if ((digitalRead(pedalPin) == HIGH) && (isPedalPressed == true)){
        
        //channel 1, CC 63 (Sustain), Value 0
        controlChange(0x00, 0x40, 0x00);
        MidiUSB.flush();
        isPedalPressed = false;
        digitalWrite(LED_BUILTIN, LOW); 
        ledDisplayZero();  //optional
        return;
        
    }

}

// First parameter is the event type (0x0B = control change).
// Second parameter is the event type, combined with the channel.
// Third parameter is the control number number (0-119).
// Fourth parameter is the control value (0-127).
void controlChange(byte channel, byte control, byte value) {
	midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
	MidiUSB.sendMIDI(event);
}