simple_client.pp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. {
  2. This simple client demonstrates the most basic features of JACK
  3. as they would be used by many applications.
  4. }
  5. program simple_client;
  6. {$MODE objfpc}{$H+}
  7. uses
  8. Jack, CTypes, SysUtils;
  9. var
  10. input_port: Pjack_port_t;
  11. output_port: Pjack_port_t;
  12. client: Pjack_client_t;
  13. {
  14. The process callback for this JACK application is called in a
  15. special realtime thread once for each audio cycle.
  16. This client does nothing more than copy data from its input
  17. port to its output port. It will exit when stopped by
  18. the user (e.g. using Ctrl-C on a unix-ish operating system)
  19. }
  20. function process (nframes: jack_nframes_t; arg: Pointer): cint; cdecl;
  21. var
  22. _in: Pjack_default_audio_sample_t;
  23. _out: Pjack_default_audio_sample_t;
  24. begin
  25. _in := jack_port_get_buffer (input_port, nframes);
  26. _out := jack_port_get_buffer (output_port, nframes);
  27. Move(_in^, _out^,
  28. SizeOf(jack_default_audio_sample_t) * nframes);
  29. Result := 0;
  30. end;
  31. {
  32. JACK calls this shutdown_callback if the server ever shuts down or
  33. decides to disconnect the client.
  34. }
  35. procedure jack_shutdown (arg: Pointer); cdecl;
  36. begin
  37. Halt (1);
  38. end;
  39. var
  40. ports: PPChar;
  41. client_name: PChar = 'simple';
  42. server_name: PChar = nil;
  43. options: jack_options_t = JackNullOption;
  44. status: jack_status_t;
  45. begin
  46. { open a client connection to the JACK server }
  47. client := jack_client_open (client_name, options, @status, server_name);
  48. if client = nil then
  49. begin
  50. Writeln(StdErr, 'jack_client_open() failed, ',
  51. 'status = $', HexStr(Ord(status), 4));
  52. if (Ord(status) and Ord(JackServerFailed)) <> 0 then
  53. begin
  54. Writeln(StdErr, 'Unable to connect to JACK server');
  55. end;
  56. Halt (1);
  57. end;
  58. if (Ord(status) and Ord(JackServerStarted)) <> 0 then
  59. begin
  60. Writeln (StdErr, 'JACK server started');
  61. end;
  62. if (Ord(status) and Ord(JackNameNotUnique)) <> 0 then
  63. begin
  64. client_name := jack_get_client_name(client);
  65. Writeln (StdErr, 'unique name `', client_name, ''' assigned');
  66. end;
  67. { tell the JACK server to call `process()' whenever
  68. there is work to be done.
  69. }
  70. jack_set_process_callback (client, @process, nil);
  71. { tell the JACK server to call `jack_shutdown()' if
  72. it ever shuts down, either entirely, or if it
  73. just decides to stop calling us.
  74. }
  75. jack_on_shutdown (client, @jack_shutdown, nil);
  76. { display the current sample rate.
  77. }
  78. Writeln ('engine sample rate: ',
  79. jack_get_sample_rate (client));
  80. { create two ports }
  81. input_port := jack_port_register (client, 'input',
  82. JACK_DEFAULT_AUDIO_TYPE,
  83. Ord(JackPortIsInput), 0);
  84. output_port := jack_port_register (client, 'output',
  85. JACK_DEFAULT_AUDIO_TYPE,
  86. Ord(JackPortIsOutput), 0);
  87. if (input_port = nil) or (output_port = nil) then
  88. begin
  89. Writeln(StdErr, 'no more JACK ports available');
  90. Halt (1);
  91. end;
  92. { Tell the JACK server that we are ready to roll. Our
  93. process() callback will start running now. }
  94. if jack_activate (client) <> 0 then
  95. begin
  96. Writeln (StdErr, 'cannot activate client');
  97. Halt (1);
  98. end;
  99. { Connect the ports. You can't do this before the client is
  100. activated, because we can't make connections to clients
  101. that aren't running. Note the confusing (but necessary)
  102. orientation of the driver backend ports: playback ports are
  103. "input" to the backend, and capture ports are "output" from
  104. it.
  105. }
  106. ports := jack_get_ports (client, nil, nil,
  107. Ord(JackPortIsPhysical) or Ord(JackPortIsOutput));
  108. if ports = nil then
  109. begin
  110. Writeln(StdErr, 'no physical capture ports');
  111. Halt (1);
  112. end;
  113. if jack_connect (client, ports[0], jack_port_name (input_port)) <> 0 then
  114. begin
  115. Writeln (StdErr, 'cannot connect input ports');
  116. end;
  117. jack_free (ports);
  118. ports := jack_get_ports (client, nil, nil,
  119. Ord(JackPortIsPhysical) or Ord(JackPortIsInput));
  120. if ports = nil then
  121. begin
  122. Writeln(StdErr, 'no physical playback ports');
  123. Halt (1);
  124. end;
  125. if jack_connect (client, jack_port_name (output_port), ports[0]) <> 0 then
  126. begin
  127. Writeln (StdErr, 'cannot connect output ports');
  128. end;
  129. jack_free (ports);
  130. { keep running until stopped by the user }
  131. repeat
  132. sleep (High(Cardinal));
  133. until False;
  134. { this is never reached but if the program
  135. had some other way to exit besides being killed,
  136. they would be important to call.
  137. }
  138. jack_client_close (client);
  139. Halt (0);
  140. end.