Advertisement
Guest User

Untitled

a guest
Jun 21st, 2017
488
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 4.63 KB | None | 0 0
  1. module patest_sine_hello;
  2.  
  3. /** @file patest_sine.c
  4.     @ingroup test_src
  5.     @brief Play a sine wave for several seconds.
  6.     @author Ross Bencina <rossb@audiomulch.com>
  7.     @author Phil Burk <philburk@softsynth.com>
  8.     @author D conversion: Jonas Kivi <satelliittipupu@y????.co.uk>
  9.     @author D2 conversion: Andrej Mitrovic <andrej.mitrovich@gmail.com>
  10.  */
  11.  
  12. import portaudio;
  13.  
  14. import std.math : sin;
  15. import std.stdio;
  16. import core.memory;
  17. import core.thread;
  18.  
  19. const NUM_SECONDS       = 1;
  20. const SAMPLE_RATE       = 44100;
  21. // buffer size
  22. const FRAMES_PER_BUFFER = 64; // 64;
  23. const TABLE_SIZE = 200;
  24.  
  25. struct paTestData
  26. {
  27.     float[TABLE_SIZE] sine;
  28.     int left_phase;
  29.     int right_phase;
  30.     char[20] message;
  31. }
  32.  
  33. /* This routine will be called by the PortAudio engine when audio is needed.
  34. ** It may be called at interrupt level on some machines so don't do anything
  35. ** that could mess up the system like calling malloc() or free().
  36. */
  37.  
  38. extern (C) static int patestCallback(void* inputBuffer, void* outputBuffer,
  39.                           uint framesPerBuffer,
  40.                           PaStreamCallbackTimeInfo* timeInfo,
  41.                           PaStreamCallbackFlags statusFlags,
  42.                           void* userData)
  43. {
  44.     paTestData* data = cast(paTestData*) userData;
  45.     float* toOut     = cast(float*) outputBuffer;
  46.     uint i;
  47.  
  48.     for (i = 0; i < framesPerBuffer; i++)
  49.     {
  50.         *toOut++         = data.sine[data.left_phase];  /* left */
  51.         *toOut++         = data.sine[data.right_phase]; /* right */
  52.         data.left_phase += 1;
  53.  
  54.         if (data.left_phase >= TABLE_SIZE)
  55.         {
  56.             data.left_phase -= TABLE_SIZE;
  57.         }
  58.  
  59.         data.right_phase += 3; /* higher pitch so we can distinguish left and right. */
  60.  
  61.         if (data.right_phase >= TABLE_SIZE)
  62.         {
  63.             data.right_phase -= TABLE_SIZE;
  64.         }
  65.     }
  66.  
  67.     return PaStreamCallbackResult.paContinue;
  68. }
  69.  
  70. /*
  71.  * This routine is called by portaudio when playback is done.
  72.  */
  73. extern (C) static void StreamFinished(void* userData)
  74. {
  75.     paTestData* data = cast(paTestData*) userData;
  76.  
  77.     writeln("Stream Completed: ", data.message);
  78. }
  79.  
  80. int main()
  81. {
  82.     writeln("PortAudio test.");
  83.  
  84.     PaStreamParameters outputParameters;
  85.     PaStream* stream;
  86.     PaError err;
  87.     paTestData data;
  88.     int i;
  89.    
  90.     writeln("PortAudio Test: output sine wave. Sample rate: ", SAMPLE_RATE, " Buffer size: ", FRAMES_PER_BUFFER);
  91.  
  92.     /* initialise sinusoidal wavetable */
  93.     for (i=0; i < TABLE_SIZE; i++)
  94.     {
  95.         data.sine[i] = cast(float) sin((cast(double) i / cast(double) TABLE_SIZE) * PI * 2.0);
  96.     }
  97.     data.left_phase = data.right_phase = 0;
  98.  
  99.     err = Pa_Initialize();
  100.  
  101.     if (err != PaErrorCode.paNoError)
  102.     {
  103.         goto error;
  104.     }
  105.  
  106.     outputParameters.device           = Pa_GetDefaultOutputDevice(); /* default output device */
  107.     outputParameters.channelCount     = 2;   /* stereo output */
  108.     outputParameters.sampleFormat     = paFloat32; /* 32 bit floating point output */
  109.     outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device).defaultLowOutputLatency;
  110.     outputParameters.hostApiSpecificStreamInfo = null;
  111.  
  112.     err = Pa_OpenStream(
  113.         &stream,
  114.         null,       /* no input */
  115.         &outputParameters,
  116.         SAMPLE_RATE,
  117.         FRAMES_PER_BUFFER,
  118.         /* we won't output out of range samples so don't bother clipping them */
  119.         paClipOff,
  120.         &patestCallback,
  121.         &data);
  122.  
  123.     if (err != PaErrorCode.paNoError)
  124.     {
  125.         goto error;
  126.     }
  127.  
  128.     writeln(data.message, "No Message");
  129.     err = Pa_SetStreamFinishedCallback(stream, &StreamFinished);
  130.  
  131.     if(err != PaErrorCode.paNoError) goto error;
  132.  
  133.     // Used as a precaution
  134.     GC.disable();
  135.    
  136.     err = Pa_StartStream(stream);
  137.     if( err != PaErrorCode.paNoError ) goto error;
  138.  
  139.     writeln("Play for seconds: ", NUM_SECONDS);
  140.     Thread.sleep( NUM_SECONDS * 10_000_000 );
  141.    
  142.     GC.enable();
  143.    
  144.     ///~ // You can exit the infinite_loop if you're in a command line with CTRL-C.
  145.     ///~ int infinite_loop = 1;
  146.     ///~ while (infinite_loop == 1)
  147.     ///~ {
  148.     ///~ }
  149.  
  150.     err = Pa_StopStream(stream);
  151.  
  152.     if( err != PaErrorCode.paNoError ) goto error;
  153.  
  154.     err = Pa_CloseStream(stream);
  155.  
  156.     if( err != PaErrorCode.paNoError ) goto error;
  157.  
  158.     Pa_Terminate();
  159.     writeln("Test finished.\n");
  160.  
  161.     return err;
  162. error:
  163.     Pa_Terminate();
  164.    
  165.     writeln("An error occured while using the portaudio stream");
  166.     writeln("Error number: ", err);
  167.     writeln("Error message: ", Pa_GetErrorText(err));
  168.     return err;
  169. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement