]> Repos - portaudio/commitdiff
Added C++ variant of paex_sine
authorrobiwan <robiwan@0f58301d-fd10-0410-b4af-bbb618454e57>
Tue, 19 Jun 2012 20:03:33 +0000 (20:03 +0000)
committerrobiwan <robiwan@0f58301d-fd10-0410-b4af-bbb618454e57>
Tue, 19 Jun 2012 20:03:33 +0000 (20:03 +0000)
examples/CMakeLists.txt
examples/paex_sine_c++.cpp [new file with mode: 0644]

index 72247ea774e49ab837516bbe9e3e8c684cc60c80..00d7e49afb8f3ddeb59a7aacae27711a043ab815 100644 (file)
@@ -5,6 +5,11 @@ MACRO(ADD_EXAMPLE appl_name)
    TARGET_LINK_LIBRARIES(${appl_name} portaudio_static)
 ENDMACRO(ADD_EXAMPLE)
 
+MACRO(ADD_EXAMPLE_CPP appl_name)
+   ADD_EXECUTABLE(${appl_name} "${appl_name}.cpp")
+   TARGET_LINK_LIBRARIES(${appl_name} portaudio_static)
+ENDMACRO(ADD_EXAMPLE_CPP)
+
 ADD_EXAMPLE(pa_devs)
 ADD_EXAMPLE(pa_fuzz)
 ADD_EXAMPLE(paex_mono_asio_channel_select)
@@ -14,6 +19,7 @@ ADD_EXAMPLE(paex_read_write_wire)
 ADD_EXAMPLE(paex_record)
 ADD_EXAMPLE(paex_saw)
 ADD_EXAMPLE(paex_sine)
+ADD_EXAMPLE_CPP(paex_sine_c++)
 ADD_EXAMPLE(paex_wmme_ac3)
 ADD_EXAMPLE(paex_wmme_surround)
 ADD_EXAMPLE(paex_write_sine)
diff --git a/examples/paex_sine_c++.cpp b/examples/paex_sine_c++.cpp
new file mode 100644 (file)
index 0000000..cc436b3
--- /dev/null
@@ -0,0 +1,240 @@
+/** @file paex_sine.c\r
+       @ingroup examples_src\r
+       @brief Play a sine wave for several seconds.\r
+       @author Ross Bencina <rossb@audiomulch.com>\r
+    @author Phil Burk <philburk@softsynth.com>\r
+*/\r
+/*\r
+ * $Id: paex_sine.c 1752 2011-09-08 03:21:55Z philburk $\r
+ *\r
+ * This program uses the PortAudio Portable Audio Library.\r
+ * For more information see: http://www.portaudio.com/\r
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining\r
+ * a copy of this software and associated documentation files\r
+ * (the "Software"), to deal in the Software without restriction,\r
+ * including without limitation the rights to use, copy, modify, merge,\r
+ * publish, distribute, sublicense, and/or sell copies of the Software,\r
+ * and to permit persons to whom the Software is furnished to do so,\r
+ * subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be\r
+ * included in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * The text above constitutes the entire PortAudio license; however, \r
+ * the PortAudio community also makes the following non-binding requests:\r
+ *\r
+ * Any person wishing to distribute modifications to the Software is\r
+ * requested to send the modifications to the original developer so that\r
+ * they can be incorporated into the canonical version. It is also \r
+ * requested that these non-binding requests be included along with the \r
+ * license above.\r
+ */\r
+#include <stdio.h>\r
+#include <math.h>\r
+#include "portaudio.h"\r
+\r
+#define NUM_SECONDS   (5)\r
+#define SAMPLE_RATE   (44100)\r
+#define FRAMES_PER_BUFFER  (64)\r
+\r
+#ifndef M_PI\r
+#define M_PI  (3.14159265)\r
+#endif\r
+\r
+#define TABLE_SIZE   (200)\r
+\r
+class Sine\r
+{\r
+public:\r
+    Sine() : stream(0), left_phase(0), right_phase(0)\r
+    {\r
+        /* initialise sinusoidal wavetable */\r
+        for( int i=0; i<TABLE_SIZE; i++ )\r
+        {\r
+            sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );\r
+        }\r
+\r
+        sprintf( message, "No Message" );\r
+    }\r
+\r
+    bool open(PaDeviceIndex index)\r
+    {\r
+        PaStreamParameters outputParameters;\r
+\r
+        outputParameters.device = index;\r
+        if (outputParameters.device == paNoDevice) {\r
+            return false;\r
+        }\r
+\r
+        outputParameters.channelCount = 2;       /* stereo output */\r
+        outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */\r
+        outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;\r
+        outputParameters.hostApiSpecificStreamInfo = NULL;\r
+\r
+        PaError err = Pa_OpenStream(\r
+            &stream,\r
+            NULL, /* no input */\r
+            &outputParameters,\r
+            SAMPLE_RATE,\r
+            FRAMES_PER_BUFFER,\r
+            paClipOff,      /* we won't output out of range samples so don't bother clipping them */\r
+            &Sine::paCallback,\r
+            this            /* Using 'this' for userData so we can cast to Sine* in paCallback method */\r
+            );\r
+\r
+        err = Pa_SetStreamFinishedCallback( stream, &Sine::paStreamFinished );\r
+\r
+        if (err != paNoError)\r
+        {\r
+            Pa_CloseStream( stream );\r
+            stream = 0;\r
+\r
+            return false;\r
+        }\r
+\r
+        return true;\r
+    }\r
+\r
+    bool close()\r
+    {\r
+        if (stream == 0)\r
+            return false;\r
+\r
+        PaError err = Pa_CloseStream( stream );\r
+        stream = 0;\r
+\r
+        return (err == paNoError);\r
+    }\r
+\r
+\r
+    bool start()\r
+    {\r
+        PaError err = Pa_StartStream( stream );\r
+\r
+        return (err == paNoError);\r
+    }\r
+\r
+    bool stop()\r
+    {\r
+        PaError err = Pa_StopStream( stream );\r
+\r
+        return (err == paNoError);\r
+    }\r
+\r
+private:\r
+    /* The instance callback, where we have access to every method/variable in object of class Sine */\r
+    int paCallbackMethod(const void *inputBuffer, void *outputBuffer,\r
+        unsigned long framesPerBuffer,\r
+        const PaStreamCallbackTimeInfo* timeInfo,\r
+        PaStreamCallbackFlags statusFlags)\r
+    {\r
+        float *out = (float*)outputBuffer;\r
+        unsigned long i;\r
+\r
+        (void) timeInfo; /* Prevent unused variable warnings. */\r
+        (void) statusFlags;\r
+        (void) inputBuffer;\r
+\r
+        for( i=0; i<framesPerBuffer; i++ )\r
+        {\r
+            *out++ = sine[left_phase];  /* left */\r
+            *out++ = sine[right_phase];  /* right */\r
+            left_phase += 1;\r
+            if( left_phase >= TABLE_SIZE ) left_phase -= TABLE_SIZE;\r
+            right_phase += 3; /* higher pitch so we can distinguish left and right. */\r
+            if( right_phase >= TABLE_SIZE ) right_phase -= TABLE_SIZE;\r
+        }\r
+\r
+        return paContinue;\r
+\r
+    }\r
+\r
+    /* This routine will be called by the PortAudio engine when audio is needed.\r
+    ** It may called at interrupt level on some machines so don't do anything\r
+    ** that could mess up the system like calling malloc() or free().\r
+    */\r
+    static int paCallback( const void *inputBuffer, void *outputBuffer,\r
+        unsigned long framesPerBuffer,\r
+        const PaStreamCallbackTimeInfo* timeInfo,\r
+        PaStreamCallbackFlags statusFlags,\r
+        void *userData )\r
+    {\r
+        /* Here we cast userData to Sine* type so we can call the instance method paCallbackMethod, we can do that since \r
+           we called Pa_OpenStream with 'this' for userData */\r
+        return ((Sine*)userData)->paCallbackMethod(inputBuffer, outputBuffer,\r
+            framesPerBuffer,\r
+            timeInfo,\r
+            statusFlags);\r
+    }\r
+\r
+\r
+    void paStreamFinishedMethod()\r
+    {\r
+        printf( "Stream Completed: %s\n", message );\r
+    }\r
+\r
+    /*\r
+     * This routine is called by portaudio when playback is done.\r
+     */\r
+    static void paStreamFinished(void* userData)\r
+    {\r
+        return ((Sine*)userData)->paStreamFinishedMethod();\r
+    }\r
+\r
+    PaStream *stream;\r
+    float sine[TABLE_SIZE];\r
+    int left_phase;\r
+    int right_phase;\r
+    char message[20];\r
+};\r
+\r
+\r
+/*******************************************************************/\r
+int main(void);\r
+int main(void)\r
+{\r
+    PaError err;\r
+    Sine sine;\r
+\r
+    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);\r
+    \r
+    err = Pa_Initialize();\r
+    if( err != paNoError ) goto error;\r
+\r
+    if (sine.open(Pa_GetDefaultOutputDevice()))\r
+    {\r
+        if (sine.start())\r
+        {\r
+            printf("Play for %d seconds.\n", NUM_SECONDS );\r
+            Pa_Sleep( NUM_SECONDS * 1000 );\r
+\r
+            sine.stop();\r
+        }\r
+\r
+        sine.close();\r
+    }\r
+\r
+    Pa_Terminate();\r
+    printf("Test finished.\n");\r
+    \r
+    return err;\r
+\r
+error:\r
+    Pa_Terminate();\r
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );\r
+    fprintf( stderr, "Error number: %d\n", err );\r
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );\r
+    return err;\r
+}\r