txt: ## dist_zef-jonathanstowe-Audio-PortAudio.md
  # Audio::PortAudio
  
  Access to audio input and output devices
  
  ![Build Status](https://github.com/Raku-Noise-Gang/Audio-PortAudio/workflows/CI/badge.svg)
  
  ## Synopsis
  
  ```
  
  use Audio::PortAudio;
  
  my $pa = Audio::PortAudio.new;
  
  # get the default stream with no inputs, 2 output channels
  # for audio encoded as 32 bit floats at 44100 samplerate
  # with a frame buffer of 512;
  my $stream = $pa.open-default-stream(0,2,Audio::PortAudio::Float32,44100,512);
  
  $stream.start;
  
  loop {
  	# get some audio data in a carray from somewhere
     # frame-count should be no more than the buffer supplied to open
  	$stream.write($carray, $frame-count);
  }
  
  
  ```
  
  See also [the examples directory](examples)
  
  ## Description
  
  This module provides a mechanism to get audio into and out of your
  program via a sound card or some other sub-system supported by the
  [portaudio](http://www.portaudio.com/), this may include "ALSA", "JACK"
  or "OSS" on Linux, "CoreAudio" on Mac and "ASIO" on Windows, (of course
  the actual support depends on how the library was built on your system.)
  
  You will need to have the portaudio library installed on your system
  to use this, it may be available as a package or come pre-installed,
  but the details will be specific to your platform.
  
  The interface is somewhat simplified in comparison to the underlying
  library and in particular only "blocking" IO is supported at the current
  time (though this does not preclude the use of the callback API in the
  future, it's just an interface that is natural to a Raku developer
  doesn't suggest itself at the moment.)
  
  It is important to note that the constraints of real-time audio data
  handling mean that you have to be careful that you allow for consistent
  and timely handing of the data to or from the device for proper results,
  you may find that for some applications you will need to avoid the use
  of any concurrency whatsoever for instance (the streaming example is
  such a case where the time budget was such that any unexpected garbage
  collection or other processor stealing activity didn't leave the process
  enough time spare to recover and the stream eventually became unusable.)
  
  Also it should be noted that some types of source API ("JACK" in
  particular,) require that you use a fixed buffer size that is consistent
  with that configured for the host service, unfortunately portaudio doesn't
  appear to provide a way of discovering this so you may need to either
  check with the source configuration or experiment to find a correct and
  working value for buffer sizes. The symptoms of this may include choppy,
  "syncopated" or "phased" output.
  
  This is based on the original work of
  [Peschwa](https://github.com/peschwa/Audio-PortAudio) which I forked and
  then just completely hijacked when I realised it could be potentially
  be made useful :) So most of the credit probably goes to him.
  
  ## Installation
  
  This module depends on having the portaudio library installed, your
  operating system may offer this is as a package that you can install
  with whatever tools the system uses (it may be installed already as it
  is quite a common dependency for audio applications,) or you may be able
  to obtain and install the source from <http://www.portaudio.com/download.html>.
  If you take the latter route you want to make sure that you install at
  least one driver for it to be useful.
  
  If you have *zef* installed you can install this module directly:
  
  ```
  zef install Audio::PortAudio
  
  ```
  
  Or if you have a copy of this source then you can do so from within the
  distribution directory:
  
  ```
  zef install .
  
  ```
  
  Depending on what drivers you have installed the tests may cause a lot of
  diagnostic output from the drivers themselves, Alsa and Jack seem to be the
  worst culprits.
  
  ## Support
  
  This probably falls into the 'experimental' category, it is definitely usable
  but I will not be surprised if you have difficulty using it because of the
  performance constraints alluded to above.
  
  It is also quite difficult to do automated tests beyond basic sanity checks, as
  it would have to be able to "hear" the output or the result of input which may
  be beyond our control so the examples stand in as a proxy for proper unit tests.
  
  Anyway if you're still reading and you do have a problem then please provide as
  much detail as possible, including the details and configuration of your sound
  card and/or host API if possible (e.g. "jack" configuration,)
  
  We'd also be delighted to hear if you don't have problems and have made something
  really cool with this, or have patches to improve the interface (in the latter
  case a working example that demonstrates that it is usable would be nice,) or
  any other suggestions via <https://github.com/Raku-Noise-Gang/Audio-PortAudio/issues>
  
  We'd be particularly interested in a Raku-ish way of expressing the portaudio
  callback API, the native subs support it, it just isn't exposed through the
  class API here.
  
  ## Licence
  
  This is free software please see the <LICENCE> file in the distribution.
  
  © Peschwa 2015
  © Jonathan Stowe 2016
  © Raku Noise Gang 2016 - 2021
  