From 46c2be7407ee11d4ece1f5c210ada2e813eb3aa9 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 7 Jan 2025 22:36:00 +0200 Subject: [PATCH] + added libjack example program midisine.pp (translated from midisine.c) --- packages/libjack/examples/midisine.pp | 139 ++++++++++++++++++++++++++ packages/libjack/fpmake.pp | 1 + 2 files changed, 140 insertions(+) create mode 100644 packages/libjack/examples/midisine.pp diff --git a/packages/libjack/examples/midisine.pp b/packages/libjack/examples/midisine.pp new file mode 100644 index 0000000000..197b61a9f6 --- /dev/null +++ b/packages/libjack/examples/midisine.pp @@ -0,0 +1,139 @@ +{ + Copyright (C) 2004 Ian Esten + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +} + +program midisine; + +{$MODE objfpc}{$H+} + +uses + CTypes, Math, SysUtils, Jack, JackMidiPort; + +var + input_port: Pjack_port_t; + output_port: Pjack_port_t; + ramp: jack_default_audio_sample_t = 0.0; + note_on: jack_default_audio_sample_t; + note: cuchar = 0; + note_frqs: array [0..127] of jack_default_audio_sample_t; + +procedure calc_note_frqs(srate: jack_default_audio_sample_t); +var + i: cint; +begin + for i := 0 to 127 do + note_frqs[i] := (2.0 * 440.0 / 32.0) * Power(2, ((jack_default_audio_sample_t(i) - 9.0) / 12.0)) / srate; +end; + +function process(nframes: jack_nframes_t; arg: Pointer): cint; cdecl; +var + i: cint; + port_buf: Pointer; + _out: Pjack_default_audio_sample_t; + in_event: jack_midi_event_t; + event_index: jack_nframes_t; + event_count: jack_nframes_t; +begin + port_buf := jack_port_get_buffer(input_port, nframes); + _out := jack_port_get_buffer (output_port, nframes); + event_index := 0; + event_count := jack_midi_get_event_count(port_buf); + if event_count > 1 then + begin + Writeln(' midisine: have ', event_count, ' events'); + for i := 0 to event_count - 1 do + begin + jack_midi_event_get(@in_event, port_buf, i); + Writeln(' event ', i, ' time is ', in_event.time, '. 1st byte is $', HexStr(in_event.buffer^, 2)); + end; + {printf("1st byte of 1st event addr is %p\n", in_events[0].buffer);} + end; + jack_midi_event_get(@in_event, port_buf, 0); + for i := 0 to nframes - 1 do + begin + if (in_event.time = i) and (event_index < event_count) then + begin + if (in_event.buffer^ and $f0) = $90 then + begin + { note on } + note := (in_event.buffer + 1)^; + note_on := 1.0; + end + else if (in_event.buffer^ and $f0) = $80 then + begin + { note off } + note := (in_event.buffer + 1)^; + note_on := 0.0; + end; + Inc(event_index); + if event_index < event_count then + jack_midi_event_get(@in_event, port_buf, event_index); + end; + ramp += note_frqs[note]; + if ramp > 1.0 then + ramp -= 2.0; + _out[i] := note_on*sin(2*PI*ramp); + end; + Result := 0; +end; + +function srate(nframes: jack_nframes_t; arg: Pointer): cint; cdecl; +begin + Writeln('the sample rate is now ', nframes, '/sec'); + calc_note_frqs(jack_default_audio_sample_t(nframes)); + Result := 0; +end; + +procedure jack_shutdown(arg: Pointer); cdecl; +begin + Halt(1); +end; + +var + client: Pjack_client_t; +begin + client := jack_client_open ('midisine', JackNullOption, nil); + if client = nil then + begin + Writeln(StdErr, 'jack server not running?'); + Halt(1); + end; + + calc_note_frqs(jack_get_sample_rate (client)); + + jack_set_process_callback (client, @process, nil); + + jack_set_sample_rate_callback (client, @srate, nil); + + jack_on_shutdown (client, @jack_shutdown, nil); + + input_port := jack_port_register (client, 'midi_in', JACK_DEFAULT_MIDI_TYPE, Ord(JackPortIsInput), 0); + output_port := jack_port_register (client, 'audio_out', JACK_DEFAULT_AUDIO_TYPE, Ord(JackPortIsOutput), 0); + + if jack_activate (client) <> 0 then + begin + Writeln(StdErr, 'cannot activate client'); + Halt(1); + end; + + { run until interrupted } + while True do + Sleep(1000); + jack_client_close(client); + Halt (0); +end. + diff --git a/packages/libjack/fpmake.pp b/packages/libjack/fpmake.pp index 61a3801fbc..7d82640432 100644 --- a/packages/libjack/fpmake.pp +++ b/packages/libjack/fpmake.pp @@ -127,6 +127,7 @@ begin P.Targets.AddExampleProgram('transport_client.pp'); P.Targets.AddExampleProgram('impulse_grabber.pp'); P.Targets.AddExampleProgram('showtime.pp'); + P.Targets.AddExampleProgram('midisine.pp'); P.NamespaceMap:='namespaces.lst';