Browse Source

+ added libjack example program midisine.pp (translated from midisine.c)

Nikolay Nikolov 7 months ago
parent
commit
46c2be7407
2 changed files with 140 additions and 0 deletions
  1. 139 0
      packages/libjack/examples/midisine.pp
  2. 1 0
      packages/libjack/fpmake.pp

+ 139 - 0
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.
+

+ 1 - 0
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';