Skip to content

Commit

Permalink
add release notes and additional comments; MIDI channel 0-based; new …
Browse files Browse the repository at this point in the history
…MidiOut.send(int,int,int)
  • Loading branch information
gewang committed Jul 10, 2024
1 parent d26712d commit d0bf2d5
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 33 deletions.
30 changes: 27 additions & 3 deletions VERSIONS
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ChucK VERSIONS log
- (updated) chugin API version from 10.1 to 10.2
- (added) chugin API for callback on shutdown
- (added) chugin API for setting array elements (thanks azaday)
- (added) overloaded constructors added (more to come)
- (added) overloaded constructors (more to come)
==================
Envelope( dur durationToTarget )
Construct an Envelope with duration to reach target (assumed to be 1.0);
Expand All @@ -33,14 +33,38 @@ ChucK VERSIONS log
==================
- (added) new member functions
==================
fun dur Envelope.ramp( dur durationToTarget, float target );
dur Envelope.ramp( dur durationToTarget, float target );
Over the given duration, ramp toward the specified target; returns the given
duration.
fun dur Envelope.ramp( float secondsToTarget, float target );
dur Envelope.ramp( float secondsToTarget, float target );
Over the given duration (in seconds), ramp toward the specified target; returns
the given duration.
==================
- (added) examples/basic/envelope2.ck -- to show Envelope.ramp() in action
- (added) new MIDI message voice message convenience functions (thanks @cviejo;
previously these are possible only through `MidiOut.send( MidiMsg msg )`:
==================
int MidiOut.send( int status, int data1, int data2 );
Send out a MIDI message consisting of one status byte and two data bytes.
int channelPressure(int channel, int pressure)
Send out a channelPressure message.
int controlChange(int channel, int controller, int value)
Send out a controlChange message.
int noteOff(int channel, int note, int velocity)
Send out a noteOff message.
int noteOn(int channel, int note, int velocity)
Send out a noteOn message.
int pitchBend(int channel, int value)
Send out a pitchBend message.
int pitchBend(int channel, int lsb, int msb)
Send out a pitchBend message with fine and coarse values.
int polyPressure(int channel, int note, int pressure)
Send out a polyPressure message.
int programChange(int channel, int program)
Send out a programChange message.
==================
- (added) examples/midi/midiout2.ck -- demonstrates using the above channel
voice messages
- (added) examples/deep/smb.ck -- a ChucK rendition of Super Mario Bros.
original theme by Koji Kondo; (meticulously) modeled in ChucK by
Wesley Burchell in 2017
Expand Down
1 change: 1 addition & 0 deletions examples/midi/midiout.ck
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// name: midiout.ck
// desc: example of sending MIDI messages
// note: for a good explanation of how MIDI messages work, see after the code
// also see midiout2.ck for sending by common channel voice message
//-----------------------------------------------------------------------------

// instantiate a MIDI out object
Expand Down
17 changes: 9 additions & 8 deletions examples/midi/midiout2.ck
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//-----------------------------------------------------------------------------
// name: midiout2.ck
// desc: example of sending MIDI messages using MidiOut only
// requires: chuck-1.5.2.5 or higher | author: cviejo
// note: for a good explanation of how MIDI messages work and sending raw midi
// messages, see midiout.ck
//-----------------------------------------------------------------------------
Expand All @@ -16,34 +17,34 @@ if( !mout.open(0) ) me.exit();
while( true )
{
<<< "sending note on message...", "" >>>;
mout.noteOn( 1, 60, 127 );
mout.noteOn( 0, 60, 127 );
1::second => now;

<<< "sending note off message...", "" >>>;
mout.noteOff( 1, 60, 0 );
mout.noteOff( 0, 60, 0 );
1::second => now;

<<< "sending control change message...", "" >>>;
mout.controlChange( 1, 14, 127 );
mout.controlChange( 0, 14, 127 );
1::second => now;

<<< "sending program change message...", "" >>>;
mout.programChange( 1, 6 );
mout.programChange( 0, 6 );
1::second => now;

<<< "sending polyphonic key pressure (aftertouch)...", "" >>>;
mout.polyPressure( 1, 60, 127 );
mout.polyPressure( 0, 60, 127 );
1::second => now;

<<< "sending channel pressure (aftertouch)...", "" >>>;
mout.channelPressure( 1, 127 );
mout.channelPressure( 0, 127 );
1::second => now;

<<< "sending pitch bend message...", "" >>>;
mout.pitchBend( 1, 96 ); // +50% or 1.00 semitone up
mout.pitchBend( 0, 96 ); // +50% or 1.00 semitone up
1::second => now;

<<< "sending fine resolution pitch bend message...", "" >>>;
mout.pitchBend( 1, 50, 96 ); // +51% or 1.01 semitone up
mout.pitchBend( 0, 50, 96 ); // +51% or 1.01 semitone up
1::second => now;
}
45 changes: 31 additions & 14 deletions src/core/chuck_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,7 @@ t_CKBOOL init_class_Midi( Chuck_Env * env )
type_engine_import_class_end( env );

// doc string
doc = "Class for sending out Midi messages.";
doc = "Class for sending out MIDI messages. Note that channel numbers are 0-based.";
// init base class
if( !type_engine_import_class_begin( env, "MidiOut", "Object",
env->global(), MidiOut_ctor, MidiOut_dtor, doc.c_str() ) )
Expand Down Expand Up @@ -864,67 +864,75 @@ t_CKBOOL init_class_Midi( Chuck_Env * env )
func->doc = "Set error printing (1 for on, 0 for off). On by default.";
if( !type_engine_import_mfun( env, func ) ) goto error;

// add send()
// add send() | 1.5.2.5 (ge) added
func = make_new_mfun( "int", "send", MidiOut_send );
func->add_arg( "int", "status" );
func->add_arg( "int", "data1" );
func->add_arg( "int", "data2" );
func->doc = "Send out a MIDI message consisting of one status byte and two data bytes.";
if( !type_engine_import_mfun( env, func ) ) goto error;

// add send()
func = make_new_mfun( "int", "send", MidiOut_send_msg );
func->add_arg( "MidiMsg", "msg" );
func->doc = "Send out a MidiMsg message.";
func->doc = "Send out a MIDI message using a MidiMsg.";
if( !type_engine_import_mfun( env, func ) ) goto error;

// add noteOn()
// add noteOn() | 1.5.2.5 (cviejo) added
func = make_new_mfun( "int", "noteOn", MidiOut_noteOn );
func->add_arg( "int", "channel" );
func->add_arg( "int", "note" );
func->add_arg( "int", "velocity" );
func->doc = "Send out a noteOn message.";
if( !type_engine_import_mfun( env, func ) ) goto error;

// add noteOff()
// add noteOff() | 1.5.2.5 (cviejo) added
func = make_new_mfun( "int", "noteOff", MidiOut_noteOff );
func->add_arg( "int", "channel" );
func->add_arg( "int", "note" );
func->add_arg( "int", "velocity" );
func->doc = "Send out a noteOff message.";
if( !type_engine_import_mfun( env, func ) ) goto error;

// add controlChange()
// add controlChange() | 1.5.2.5 (cviejo) added
func = make_new_mfun( "int", "controlChange", MidiOut_controlChange );
func->add_arg( "int", "channel" );
func->add_arg( "int", "controller" );
func->add_arg( "int", "value" );
func->doc = "Send out a controlChange message.";
if( !type_engine_import_mfun( env, func ) ) goto error;

// add programChange()
// add programChange() | 1.5.2.5 (cviejo) added
func = make_new_mfun( "int", "programChange", MidiOut_programChange );
func->add_arg( "int", "channel" );
func->add_arg( "int", "program" );
func->doc = "Send out a programChange message.";
if( !type_engine_import_mfun( env, func ) ) goto error;

// add pitchBend()
// add pitchBend() | 1.5.2.5 (cviejo) added
func = make_new_mfun( "int", "pitchBend", MidiOut_pitchBend );
func->add_arg( "int", "channel" );
func->add_arg( "int", "value" );
func->doc = "Send out a pitchBend message.";
if( !type_engine_import_mfun( env, func ) ) goto error;

// add pitchBend() - fine resolution
// add pitchBend() - fine resolution | 1.5.2.5 (cviejo) added
func = make_new_mfun( "int", "pitchBend", MidiOut_pitchBend_fine );
func->add_arg( "int", "channel" );
func->add_arg( "int", "lsb" );
func->add_arg( "int", "msb" );
func->doc = "Send out a pitchBend message with fine and coarse values.";
if( !type_engine_import_mfun( env, func ) ) goto error;

// add polyPressure()
// add polyPressure() | 1.5.2.5 (cviejo) added
func = make_new_mfun( "int", "polyPressure", MidiOut_polyPressure );
func->add_arg( "int", "channel" );
func->add_arg( "int", "note" );
func->add_arg( "int", "pressure" );
func->doc = "Send out a polyPressure message.";
if( !type_engine_import_mfun( env, func ) ) goto error;

// add channelPressure()
// add channelPressure() | 1.5.2.5 (cviejo) added
func = make_new_mfun( "int", "channelPressure", MidiOut_channelPressure );
func->add_arg( "int", "channel" );
func->add_arg( "int", "pressure" );
Expand All @@ -933,6 +941,7 @@ t_CKBOOL init_class_Midi( Chuck_Env * env )

// add examples
if( !type_engine_import_add_ex( env, "midi/midiout.ck" ) ) goto error;
if( !type_engine_import_add_ex( env, "midi/midiout2.ck" ) ) goto error;

// add member variable
MidiOut_offset_data = type_engine_import_mvar( env, "int", "@MidiOut_data", FALSE );
Expand Down Expand Up @@ -2478,7 +2487,16 @@ CK_DLL_MFUN( MidiOut_printerr )
mout->set_suppress( !print_or_not );
}

CK_DLL_MFUN( MidiOut_send )
CK_DLL_MFUN( MidiOut_send ) // 1.5.2.5 | (ge) added
{
MidiOut * mout = (MidiOut *)OBJ_MEMBER_INT(SELF, MidiOut_offset_data);
t_CKBYTE status = (t_CKBYTE)GET_NEXT_INT(ARGS);
t_CKBYTE data1 = (t_CKBYTE)GET_NEXT_INT(ARGS);
t_CKBYTE data2 = (t_CKBYTE)GET_NEXT_INT(ARGS);
RETURN->v_int = mout->send( status, data1, data2 );
}

CK_DLL_MFUN( MidiOut_send_msg )
{
MidiOut * mout = (MidiOut *)OBJ_MEMBER_INT(SELF, MidiOut_offset_data);
Chuck_Object * fake_msg = GET_CK_OBJECT(ARGS);
Expand All @@ -2489,7 +2507,7 @@ CK_DLL_MFUN( MidiOut_send )
RETURN->v_int = mout->send( &the_msg );
}

CK_DLL_MFUN( MidiOut_noteOn )
CK_DLL_MFUN( MidiOut_noteOn ) // 1.5.2.5 (cviejo) added
{
MidiOut * mout = (MidiOut *)OBJ_MEMBER_INT(SELF, MidiOut_offset_data);
t_CKINT channel = GET_NEXT_INT(ARGS);
Expand Down Expand Up @@ -2541,7 +2559,6 @@ CK_DLL_MFUN( MidiOut_pitchBend_fine )
RETURN->v_int = mout->pitchbendFine( channel, lsb, msb );
}


CK_DLL_MFUN( MidiOut_polyPressure )
{
MidiOut * mout = (MidiOut *)OBJ_MEMBER_INT(SELF, MidiOut_offset_data);
Expand Down
1 change: 1 addition & 0 deletions src/core/chuck_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ CK_DLL_MFUN( MidiOut_num );
CK_DLL_MFUN( MidiOut_name );
CK_DLL_MFUN( MidiOut_printerr );
CK_DLL_MFUN( MidiOut_send );
CK_DLL_MFUN( MidiOut_send_msg );
CK_DLL_MFUN( MidiOut_noteOn );
CK_DLL_MFUN( MidiOut_noteOff );
CK_DLL_MFUN( MidiOut_controlChange );
Expand Down
19 changes: 11 additions & 8 deletions src/core/midiio_rtmidi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ t_CKUINT MidiOut::send( t_CKBYTE status )
// note: previously, this was sending a 3 byte message with data2 = 0, this was
// causing a problem on macOS (only) where rtmidi was sending two program
// change messages instead of one. This was fixed by sending a 2 byte
// message.
// message | 1.5.2.5 (cviejo)
//-----------------------------------------------------------------------------
t_CKUINT MidiOut::send( t_CKBYTE status, t_CKBYTE data1 )
{
Expand Down Expand Up @@ -225,7 +225,7 @@ t_CKBOOL MidiOut::close( )
// desc: note on message
//-----------------------------------------------------------------------------
t_CKUINT MidiOut::noteon( t_CKUINT channel, t_CKUINT note, t_CKUINT velocity )
{ return this->send( (t_CKBYTE)(MIDI_NOTEON + channel - 1), note, velocity ); }
{ return this->send( (t_CKBYTE)(MIDI_NOTEON + channel), note, velocity ); }



Expand All @@ -235,7 +235,7 @@ t_CKUINT MidiOut::noteon( t_CKUINT channel, t_CKUINT note, t_CKUINT velocity )
// desc: note off message
//-----------------------------------------------------------------------------
t_CKUINT MidiOut::noteoff( t_CKUINT channel, t_CKUINT note, t_CKUINT velocity )
{ return this->send( (t_CKBYTE)(MIDI_NOTEOFF + channel - 1), note, velocity ); }
{ return this->send( (t_CKBYTE)(MIDI_NOTEOFF + channel), note, velocity ); }



Expand All @@ -245,7 +245,7 @@ t_CKUINT MidiOut::noteoff( t_CKUINT channel, t_CKUINT note, t_CKUINT velocity )
// desc: polypress message
//-----------------------------------------------------------------------------
t_CKUINT MidiOut::polypress( t_CKUINT channel, t_CKUINT note, t_CKUINT pressure )
{ return this->send( (t_CKBYTE)(MIDI_POLYPRESS + channel - 1), note, pressure ); }
{ return this->send( (t_CKBYTE)(MIDI_POLYPRESS + channel), note, pressure ); }



Expand All @@ -255,7 +255,7 @@ t_CKUINT MidiOut::polypress( t_CKUINT channel, t_CKUINT note, t_CKUINT pressure
// desc: ctrl change message
//-----------------------------------------------------------------------------
t_CKUINT MidiOut::ctrlchange( t_CKUINT channel, t_CKUINT ctrl_num, t_CKUINT ctrl_val )
{ return this->send( (t_CKBYTE)(MIDI_CTRLCHANGE + channel - 1), ctrl_num, ctrl_val ); }
{ return this->send( (t_CKBYTE)(MIDI_CTRLCHANGE + channel), ctrl_num, ctrl_val ); }



Expand All @@ -265,7 +265,7 @@ t_CKUINT MidiOut::ctrlchange( t_CKUINT channel, t_CKUINT ctrl_num, t_CKUINT ctrl
// desc: prog change message
//-----------------------------------------------------------------------------
t_CKUINT MidiOut::progchange( t_CKUINT channel, t_CKUINT patch )
{ return this->send( (t_CKBYTE)(MIDI_PROGCHANGE + channel - 1), patch ); }
{ return this->send( (t_CKBYTE)(MIDI_PROGCHANGE + channel), patch ); }



Expand All @@ -275,7 +275,8 @@ t_CKUINT MidiOut::progchange( t_CKUINT channel, t_CKUINT patch )
// desc: chan press
//-----------------------------------------------------------------------------
t_CKUINT MidiOut::chanpress( t_CKUINT channel, t_CKUINT pressure )
{ return this->send( (t_CKBYTE)(MIDI_CHANPRESS + channel - 1), pressure ); }
{ return this->send( (t_CKBYTE)(MIDI_CHANPRESS + channel), pressure ); }




Expand All @@ -284,7 +285,8 @@ t_CKUINT MidiOut::chanpress( t_CKUINT channel, t_CKUINT pressure )
// desc: pitch bend
//-----------------------------------------------------------------------------
t_CKUINT MidiOut::pitchbendFine( t_CKUINT channel, t_CKUINT lsb, t_CKUINT msb)
{ return this->send( (t_CKBYTE)(MIDI_PITCHBEND + channel - 1), lsb, msb ); }
{ return this->send( (t_CKBYTE)(MIDI_PITCHBEND + channel), lsb, msb ); }




Expand All @@ -297,6 +299,7 @@ t_CKUINT MidiOut::pitchbend( t_CKUINT channel, t_CKUINT bend_val )




//-----------------------------------------------------------------------------
// name: allnotesoff()
// desc: allnotesoff
Expand Down

0 comments on commit d0bf2d5

Please sign in to comment.