Thread: Creating and passing a void through for userdata with portaudio

  1. #1
    Registered User
    Join Date
    Apr 2022
    Posts
    2

    Creating and passing a void through for userdata with portaudio

    I am a complete C/C++ noob and been hacking away at my 1st project which is basically just using GitHub - orazdow/PortAudio-Wrapper: C++ wrapper for PortAudio & GitHub - robin1001/beamforming

    Where my hack main() .cpp looks something like this

    Code:
    #include "pa.h"
    #include "tdoa.h"
    #include "ds.h"
    #include "parse-option.h"
    #include <chrono>
    using namespace std;
    using namespace std::chrono;
    struct paConfig
    {
        int channels;
        int margin;
    };
    
    
    void paFunc(const float* in, float* out, long frames, void* data){    
      auto start = high_resolution_clock::now();    
      int num_channel = 2;
      int margin = 6;
      float *out_pcm = (float *)calloc(sizeof(float), frames);
      int *tdoa = (int *)calloc(sizeof(int), num_channel);
      // rearrange channel data
      float *in_data = (float *)calloc(sizeof(float), 
        frames * num_channel);
      float *beam_data = (float *)calloc(sizeof(float), 
        frames * num_channel);
    
    
      for (int j = 0; j < num_channel; j++) {
        for (int k = 0; k < frames; k++) {
          in_data[j + k] = in[k * num_channel + j];
                }
        for (int k = 0; k < frames; k++) {
                    beam_data[j + k] = in[k * num_channel + j];
                }
            }        
      // calc delay
      int tao = margin < frames / 2 ? margin : frames / 2;
      GccPhatTdoa(in_data, num_channel, frames, 0, tao, tdoa);
      for (int j = 0; j < num_channel; j++) {
        printf("%d ", tdoa[j]);
        }
      printf("\n");
    
    
      DelayAndSum(beam_data, num_channel, frames, tdoa, out_pcm);
      
      float max = 0.0;
      float average = 0.0;
      for (int k = 0; k < frames; k++) {
        out[k] = out_pcm[k];
        float val = out_pcm[k];
        if( val < 0 ) val = -val; /* ABS */
        if( val > max )
           {
             max = val;
             }
        average += val;
        }
        
      average = average / (float)frames;
      printf("sample max amplitude = %f\n", max );
      printf("sample average = %f\n", average );
      auto stop = high_resolution_clock::now();
      auto duration = duration_cast<milliseconds>(stop - start);
      printf("milliseconds = %ld\n", duration);
      free(beam_data);
      free(in_data);
      free(out_pcm);
      free(tdoa);
    }
    
    
    int main(int argc, char *argv[]) {
      const char *usage = "Do delay and sum beamforming\n"
        "Usage: apply-delay-and-sum input_device output_device\n";
      ParseOptions po(usage);
    
    
      int input_device = 1;
      po.Register("input_device", &input_device, 
        "multichannel input device index");
      int output_device = 1;
      po.Register("output_device", &output_device, 
        "single channel output device index");
      int frames = 4000;
      po.Register("frames", &frames, 
        "frame buffer size");        
      int channels = 2;
      po.Register("channels", &channels, 
        "mic input channels");
      int margin = 16;
      po.Register("margin", &margin, 
        "constraint for tdoa estimation");
      int sample_rate = 44100;
      po.Register("sample_rate", &sample_rate, 
        "sample rate");
      po.Read(argc, argv);
    
    
      //if (po.NumArgs() != 2) {
        //po.PrintUsage();
        //exit(1);
      //}
      struct paConfig config;
      config.channels = channels;
      config.margin = margin;
      Pa a(paFunc, channels, 1, sample_rate, frames, NULL);
      a.listDevices();
      a.getDeviceInfo(input_device);
      a.getDeviceInfo(output_device);
      printf("input=%d output=%d frames=%d channels=%d margin=%d sample_rate=%d", input_device, output_device, frames, channels, margin, sample_rate);
      a.setInputDevice(input_device);
      a.setOutputDevice(output_device);
      a.start(Pa::waitForKey);
      return 0;
      }
    Currently the callback call has the userdata set to Null.
    `Pa a(paFunc, channels, 1, sample_rate, frames, NULL);`
    Where it should come through as 'void* data'
    void paFunc(const float* in, float* out, long frames, void* data)

    I am presuming a struct with each user parameter I want to send is quite easy but everything I have tried so far has failed and its just my total noobness where you can cast a struct ` /* Cast data passed through stream to our structure. */ paTestData *data = (paTestData*)userData; `

    I just can not seen to figure out how and presuming it pretty easy and wondering if anyone can give me a better example than the one at

    PortAudio: Writing a Callback Function



  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,121
    You would define the start of your function like this
    Code:
    void paFunc(const float* in, float* out, long frames, void* data){    
      auto start = high_resolution_clock::now();    
      paConfig *config = reinterpret_cast<paConfig*>(data);
      // now use config->channels
      int num_channel = 2;
      // now use config->margin
      int margin = 6;
    Your call in main would be
    Code:
    Pa a(paFunc, channels, 1, sample_rate, frames, &config);
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Linker Issue - Getting PortAudio to work with Code::Blocks
    By samGwilliam in forum C++ Programming
    Replies: 9
    Last Post: 06-16-2019, 05:17 PM
  2. (Rookie) Creating a void Function error
    By Joel Hernández in forum C++ Programming
    Replies: 7
    Last Post: 12-18-2012, 12:39 AM
  3. Passing void pointer by reference
    By sakura in forum C Programming
    Replies: 3
    Last Post: 08-23-2012, 01:16 AM
  4. Passing a variable in void to another void function
    By stevedawg85 in forum C++ Programming
    Replies: 5
    Last Post: 05-05-2006, 06:17 PM
  5. Passing a double to function with void *
    By foniks munkee in forum C Programming
    Replies: 5
    Last Post: 03-08-2002, 10:09 PM

Tags for this Thread