30#ifndef APF_PORTAUDIO_POLICY_H 
   31#define APF_PORTAUDIO_POLICY_H 
   40#ifndef APF_MIMOPROCESSOR_INTERFACE_POLICY 
   41#define APF_MIMOPROCESSOR_INTERFACE_POLICY apf::portaudio_policy 
   53    using sample_type = float;
 
   57    struct portaudio_error : std::runtime_error
 
   59      portaudio_error(PaError error)
 
   60        : std::runtime_error(
"PortAudio: "+std::string(Pa_GetErrorText(error)))
 
   66    static std::string device_info()
 
   68      auto err = Pa_Initialize();
 
   69      if (err != paNoError) 
throw portaudio_error(err);
 
   72      for (
int i = 0; i < Pa_GetDeviceCount(); ++i)
 
   74        result = result + 
"Device ID " + 
str::A2S(i) + 
": " 
   75          + Pa_GetDeviceInfo(i)->name + 
"\n";
 
   84      unsigned long sample_format = 0x00000001 | 0x80000000;
 
   86      auto inputParameters = PaStreamParameters();
 
   87      auto outputParameters = PaStreamParameters();
 
   89      inputParameters.channelCount = _next_input_id;
 
   90      inputParameters.device = _device_id;
 
   91      inputParameters.hostApiSpecificStreamInfo = 
nullptr;
 
   92      inputParameters.sampleFormat = sample_format;
 
   93      inputParameters.suggestedLatency
 
   96      outputParameters.channelCount = _next_output_id;
 
   97      outputParameters.device = _device_id;
 
   98      outputParameters.hostApiSpecificStreamInfo = 
nullptr;
 
   99      outputParameters.sampleFormat = sample_format;
 
  100      outputParameters.suggestedLatency
 
  103      auto err = Pa_OpenStream(&_stream, &inputParameters, &outputParameters
 
  104          , _sample_rate, _block_size, 0, _pa_callback, 
this);
 
  106      if (err != paNoError) 
throw portaudio_error(err);
 
  108      err = Pa_StartStream(_stream);
 
  109      if (err != paNoError) 
throw portaudio_error(err);
 
  115      auto err = Pa_StopStream(_stream);
 
  116      if (err != paNoError) 
throw portaudio_error(err);
 
  120    unsigned long block_size()
 const { 
return _block_size; }
 
  121    int sample_rate()
 const { 
return _sample_rate; }
 
  123    int in_channels()
 const { 
return _next_input_id; }
 
  124    int out_channels()
 const { 
return _next_output_id; }
 
  128    int get_real_time_priority()
 const { 
return -1; }
 
  133      : _sample_rate(p.get<int>(
"sample_rate"))
 
  134      , _block_size(p.get<unsigned long>(
"block_size"))
 
  135      , _device_id(p.get(
"device_id", 0))
 
  139      auto err = Pa_Initialize();
 
  140      if (err != paNoError) 
throw portaudio_error(err);
 
  146      Pa_CloseStream(_stream);  
 
  151    static int _pa_callback(
const void *input, 
void *output
 
  152        , 
unsigned long frameCount, 
const PaStreamCallbackTimeInfo* timeInfo
 
  153        , PaStreamCallbackFlags statusFlags, 
void *userData)
 
  159          , output, frameCount);
 
  162    int pa_callback(
const void *input, 
void *output, 
unsigned long frameCount)
 
  165      assert(frameCount == this->block_size());
 
  167      _in = 
static_cast<sample_type* const*
>(input);
 
  168      _out = 
static_cast<sample_type* const*
>(output);
 
  176    virtual void process() = 0;
 
  180    int get_next_input_id() { 
return _next_input_id++; }
 
  183    int get_next_output_id() { 
return _next_output_id++; }
 
  185    const int _sample_rate;
 
  186    const unsigned long _block_size;
 
  187    const int _device_id;
 
  191    sample_type* 
const* _in;
 
  192    sample_type* 
const* _out;
 
  197class portaudio_policy::Input
 
  200    using iterator = sample_type 
const*;
 
  202    struct buffer_type : has_begin_and_end<iterator> { 
friend class Input; };
 
  206      this->buffer._begin = _parent._in[_id];
 
  207      this->buffer._end   = this->buffer._begin + _parent.block_size();
 
  215      , _id(_parent.get_next_input_id())
 
  225class portaudio_policy::Output
 
  228    using iterator = sample_type*;
 
  230    struct buffer_type : has_begin_and_end<iterator> { 
friend class Output; };
 
  234      this->buffer._begin = _parent._out[_id];
 
  235      this->buffer._end   = this->buffer._begin + _parent.block_size();
 
  243      , _id(_parent.get_next_output_id())
 
interface_policy using PortAudio.
 
portaudio_policy(const parameter_map &p=parameter_map())
Constructor.
 
~portaudio_policy()
Protected destructor.
 
Several more or less useful iterators and some macros.
 
std::string A2S(const T &input)
Converter "Anything to String".
 
Audio Processing Framework.
 
A "dictionary" for parameters.
 
A "dictionary" for parameters.