Collection of tools useful for audio production
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 lines
5.5KB

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # Imports (Global)
  4. from ctypes import *
  5. from os import system
  6. from sys import version_info
  7. from signal import signal, SIGINT, SIGTERM
  8. from time import sleep
  9. # --------------------------------------------------
  10. # Test for python 3.x
  11. if (version_info >= (3,0)):
  12. PYTHON3 = True
  13. else:
  14. PYTHON3 = False
  15. # --------------------------------------------------
  16. # Global loop check
  17. global doLoop, doRunNow
  18. doLoop = True
  19. doRunNow = True
  20. # --------------------------------------------------
  21. # Global JACK variables
  22. global sample_rate, buffer_size
  23. sample_rate = 44100
  24. buffer_size = 1024
  25. # --------------------------------------------------
  26. # JACK ctypes implementation
  27. jacklib = cdll.LoadLibrary("libjack.so.0")
  28. class jack_client_t(Structure):
  29. _fields_ = []
  30. jack_nframes_t = c_uint32
  31. JackBufferSizeCallback = CFUNCTYPE(c_int, jack_nframes_t, c_void_p)
  32. JackShutdownCallback = CFUNCTYPE(None, c_void_p)
  33. jacklib.jack_client_open.argtypes = [c_char_p, c_int, POINTER(c_int)]
  34. jacklib.jack_client_open.restype = POINTER(jack_client_t)
  35. jacklib.jack_client_close.argtypes = [POINTER(jack_client_t)]
  36. jacklib.jack_client_close.restype = c_int
  37. jacklib.jack_activate.argtypes = [POINTER(jack_client_t)]
  38. jacklib.jack_activate.restype = c_int
  39. jacklib.jack_deactivate.argtypes = [POINTER(jack_client_t)]
  40. jacklib.jack_deactivate.restype = c_int
  41. jacklib.jack_connect.argtypes = [POINTER(jack_client_t), c_char_p, c_char_p]
  42. jacklib.jack_connect.restype = c_int
  43. jacklib.jack_get_sample_rate.argtypes = [POINTER(jack_client_t)]
  44. jacklib.jack_get_sample_rate.restype = jack_nframes_t
  45. jacklib.jack_get_buffer_size.argtypes = [POINTER(jack_client_t)]
  46. jacklib.jack_get_buffer_size.restype = jack_nframes_t
  47. jacklib.jack_on_shutdown.argtypes = [POINTER(jack_client_t), JackShutdownCallback, c_void_p]
  48. jacklib.jack_on_shutdown.restype = None
  49. jacklib.jack_set_buffer_size_callback.argtypes = [POINTER(jack_client_t), JackBufferSizeCallback, c_void_p]
  50. jacklib.jack_set_buffer_size_callback.restype = c_int
  51. def jack_client_open(client_name, options, status):
  52. if (PYTHON3): client_name = client_name.encode("ascii")
  53. return jacklib.jack_client_open(client_name, options, status)
  54. def jack_client_close(client):
  55. return jacklib.jack_client_close(client)
  56. def jack_activate(client):
  57. return jacklib.jack_activate(client)
  58. def jack_deactivate(client):
  59. return jacklib.jack_deactivate(client)
  60. def jack_connect(client, source_port, destination_port):
  61. if (PYTHON3): source_port = source_port.encode("ascii")
  62. if (PYTHON3): destination_port = destination_port.encode("ascii")
  63. return jacklib.jack_connect(client, source_port, destination_port)
  64. def jack_get_sample_rate(client):
  65. return jacklib.jack_get_sample_rate(client)
  66. def jack_get_buffer_size(client):
  67. return jacklib.jack_get_buffer_size(client)
  68. def jack_on_shutdown(client, shutdown_callback, arg):
  69. global _shutdown_callback
  70. _shutdown_callback = JackShutdownCallback(shutdown_callback)
  71. jacklib.jack_on_shutdown(client, _shutdown_callback, arg)
  72. def jack_set_buffer_size_callback(client, bufsize_callback, arg):
  73. global _bufsize_callback
  74. _bufsize_callback = JackBufferSizeCallback(bufsize_callback)
  75. return jacklib.jack_set_buffer_size_callback(client, _bufsize_callback, arg)
  76. # --------------------------------------------------
  77. # quit on SIGINT or SIGTERM
  78. def signal_handler(sig, frame=0):
  79. global doLoop
  80. doLoop = False
  81. # --------------------------------------------------
  82. # listen to jack buffer size changes
  83. def buffer_size_callback(new_buffer_size, arg):
  84. global doRunNow, buffer_size
  85. buffer_size = new_buffer_size
  86. doRunNow = True
  87. return 0
  88. # --------------------------------------------------
  89. # listen to jack shutdown
  90. def shutdown_callback(arg):
  91. global doLoop
  92. doLoop = False
  93. # --------------------------------------------------
  94. # run alsa_in and alsa_out
  95. def run_alsa_bridge():
  96. global sample_rate, buffer_size
  97. system("killall alsa_in alsa_out zita-a2j zita-j2a pulseaudio")
  98. #if (False):
  99. system("env JACK_SAMPLE_RATE=%i JACK_PERIOD_SIZE=%i alsa_in -j alsa2jack -d cloop -q 1 2>&1 1> /dev/null &" % (sample_rate, buffer_size))
  100. system("env JACK_SAMPLE_RATE=%i JACK_PERIOD_SIZE=%i alsa_out -j jack2alsa -d ploop -q 1 2>&1 1> /dev/null &" % (sample_rate, buffer_size))
  101. #else:
  102. #system("env JACK_SAMPLE_RATE=%i JACK_PERIOD_SIZE=%i zita-a2j -j alsa2jack -d hw:Loopback,1,0 -r 44100 &" % (sample_rate, buffer_size))
  103. #system("env JACK_SAMPLE_RATE=%i JACK_PERIOD_SIZE=%i zita-j2a -j jack2alsa -d hw:Loopback,1,1 -r 44100 &" % (sample_rate, buffer_size))
  104. # Pause it for a bit, and connect to the system ports
  105. sleep(1)
  106. jack_connect(client, "alsa2jack:capture_1", "system:playback_1")
  107. jack_connect(client, "alsa2jack:capture_2", "system:playback_2")
  108. jack_connect(client, "system:capture_1", "jack2alsa:playback_1")
  109. jack_connect(client, "system:capture_2", "jack2alsa:playback_2")
  110. #--------------- main ------------------
  111. if __name__ == '__main__':
  112. # Init JACK client
  113. client = jack_client_open("jack-aloop-daemon", 0, None)
  114. if (not client):
  115. quit()
  116. jack_set_buffer_size_callback(client, buffer_size_callback, None)
  117. jack_on_shutdown(client, shutdown_callback, None)
  118. jack_activate(client)
  119. # Quit when requested
  120. signal(SIGINT, signal_handler)
  121. signal(SIGTERM, signal_handler)
  122. # Get initial values
  123. sample_rate = jack_get_sample_rate(client)
  124. buffer_size = jack_get_buffer_size(client)
  125. # Keep running until told otherwise
  126. while (doLoop):
  127. if (doRunNow):
  128. doRunNow = False
  129. run_alsa_bridge()
  130. sleep(1)
  131. # Close JACK client
  132. jack_deactivate(client)
  133. jack_client_close(client)