To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

The primary repository for this project is hosted at https://github.com/sonic-visualiser/sv-dependency-builds .
This repository is a read-only copy which is updated automatically every hour.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / src / portaudio_20161030_catalina_patch / examples / paex_sine_c++.cpp @ 164:9fa11135915a

History | View | Annotate | Download (7.75 KB)

1
/** @file paex_sine.c
2
        @ingroup examples_src
3
        @brief Play a sine wave for several seconds.
4
        @author Ross Bencina <rossb@audiomulch.com>
5
    @author Phil Burk <philburk@softsynth.com>
6
*/
7
/*
8
 * $Id: paex_sine.c 1752 2011-09-08 03:21:55Z philburk $
9
 *
10
 * This program uses the PortAudio Portable Audio Library.
11
 * For more information see: http://www.portaudio.com/
12
 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
13
 *
14
 * Permission is hereby granted, free of charge, to any person obtaining
15
 * a copy of this software and associated documentation files
16
 * (the "Software"), to deal in the Software without restriction,
17
 * including without limitation the rights to use, copy, modify, merge,
18
 * publish, distribute, sublicense, and/or sell copies of the Software,
19
 * and to permit persons to whom the Software is furnished to do so,
20
 * subject to the following conditions:
21
 *
22
 * The above copyright notice and this permission notice shall be
23
 * included in all copies or substantial portions of the Software.
24
 *
25
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
28
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
29
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
30
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32
 */
33

    
34
/*
35
 * The text above constitutes the entire PortAudio license; however, 
36
 * the PortAudio community also makes the following non-binding requests:
37
 *
38
 * Any person wishing to distribute modifications to the Software is
39
 * requested to send the modifications to the original developer so that
40
 * they can be incorporated into the canonical version. It is also 
41
 * requested that these non-binding requests be included along with the 
42
 * license above.
43
 */
44
#include <stdio.h>
45
#include <math.h>
46
#include "portaudio.h"
47

    
48
#define NUM_SECONDS   (5)
49
#define SAMPLE_RATE   (44100)
50
#define FRAMES_PER_BUFFER  (64)
51

    
52
#ifndef M_PI
53
#define M_PI  (3.14159265)
54
#endif
55

    
56
#define TABLE_SIZE   (200)
57

    
58
class Sine
59
{
60
public:
61
    Sine() : stream(0), left_phase(0), right_phase(0)
62
    {
63
        /* initialise sinusoidal wavetable */
64
        for( int i=0; i<TABLE_SIZE; i++ )
65
        {
66
            sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
67
        }
68

    
69
        sprintf( message, "No Message" );
70
    }
71

    
72
    bool open(PaDeviceIndex index)
73
    {
74
        PaStreamParameters outputParameters;
75

    
76
        outputParameters.device = index;
77
        if (outputParameters.device == paNoDevice) {
78
            return false;
79
        }
80

    
81
        const PaDeviceInfo* pInfo = Pa_GetDeviceInfo(index);
82
        if (pInfo != 0)
83
        {
84
            printf("Output device name: '%s'\r", pInfo->name);
85
        }
86

    
87
        outputParameters.channelCount = 2;       /* stereo output */
88
        outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
89
        outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
90
        outputParameters.hostApiSpecificStreamInfo = NULL;
91

    
92
        PaError err = Pa_OpenStream(
93
            &stream,
94
            NULL, /* no input */
95
            &outputParameters,
96
            SAMPLE_RATE,
97
            paFramesPerBufferUnspecified,
98
            paClipOff,      /* we won't output out of range samples so don't bother clipping them */
99
            &Sine::paCallback,
100
            this            /* Using 'this' for userData so we can cast to Sine* in paCallback method */
101
            );
102

    
103
        if (err != paNoError)
104
        {
105
            /* Failed to open stream to device !!! */
106
            return false;
107
        }
108

    
109
        err = Pa_SetStreamFinishedCallback( stream, &Sine::paStreamFinished );
110

    
111
        if (err != paNoError)
112
        {
113
            Pa_CloseStream( stream );
114
            stream = 0;
115

    
116
            return false;
117
        }
118

    
119
        return true;
120
    }
121

    
122
    bool close()
123
    {
124
        if (stream == 0)
125
            return false;
126

    
127
        PaError err = Pa_CloseStream( stream );
128
        stream = 0;
129

    
130
        return (err == paNoError);
131
    }
132

    
133

    
134
    bool start()
135
    {
136
        if (stream == 0)
137
            return false;
138

    
139
        PaError err = Pa_StartStream( stream );
140

    
141
        return (err == paNoError);
142
    }
143

    
144
    bool stop()
145
    {
146
        if (stream == 0)
147
            return false;
148

    
149
        PaError err = Pa_StopStream( stream );
150

    
151
        return (err == paNoError);
152
    }
153

    
154
private:
155
    /* The instance callback, where we have access to every method/variable in object of class Sine */
156
    int paCallbackMethod(const void *inputBuffer, void *outputBuffer,
157
        unsigned long framesPerBuffer,
158
        const PaStreamCallbackTimeInfo* timeInfo,
159
        PaStreamCallbackFlags statusFlags)
160
    {
161
        float *out = (float*)outputBuffer;
162
        unsigned long i;
163

    
164
        (void) timeInfo; /* Prevent unused variable warnings. */
165
        (void) statusFlags;
166
        (void) inputBuffer;
167

    
168
        for( i=0; i<framesPerBuffer; i++ )
169
        {
170
            *out++ = sine[left_phase];  /* left */
171
            *out++ = sine[right_phase];  /* right */
172
            left_phase += 1;
173
            if( left_phase >= TABLE_SIZE ) left_phase -= TABLE_SIZE;
174
            right_phase += 3; /* higher pitch so we can distinguish left and right. */
175
            if( right_phase >= TABLE_SIZE ) right_phase -= TABLE_SIZE;
176
        }
177

    
178
        return paContinue;
179

    
180
    }
181

    
182
    /* This routine will be called by the PortAudio engine when audio is needed.
183
    ** It may called at interrupt level on some machines so don't do anything
184
    ** that could mess up the system like calling malloc() or free().
185
    */
186
    static int paCallback( const void *inputBuffer, void *outputBuffer,
187
        unsigned long framesPerBuffer,
188
        const PaStreamCallbackTimeInfo* timeInfo,
189
        PaStreamCallbackFlags statusFlags,
190
        void *userData )
191
    {
192
        /* Here we cast userData to Sine* type so we can call the instance method paCallbackMethod, we can do that since 
193
           we called Pa_OpenStream with 'this' for userData */
194
        return ((Sine*)userData)->paCallbackMethod(inputBuffer, outputBuffer,
195
            framesPerBuffer,
196
            timeInfo,
197
            statusFlags);
198
    }
199

    
200

    
201
    void paStreamFinishedMethod()
202
    {
203
        printf( "Stream Completed: %s\n", message );
204
    }
205

    
206
    /*
207
     * This routine is called by portaudio when playback is done.
208
     */
209
    static void paStreamFinished(void* userData)
210
    {
211
        return ((Sine*)userData)->paStreamFinishedMethod();
212
    }
213

    
214
    PaStream *stream;
215
    float sine[TABLE_SIZE];
216
    int left_phase;
217
    int right_phase;
218
    char message[20];
219
};
220

    
221
class ScopedPaHandler
222
{
223
public:
224
    ScopedPaHandler()
225
        : _result(Pa_Initialize())
226
    {
227
    }
228
    ~ScopedPaHandler()
229
    {
230
        if (_result == paNoError)
231
        {
232
            Pa_Terminate();
233
        }
234
    }
235

    
236
    PaError result() const { return _result; }
237

    
238
private:
239
    PaError _result;
240
};
241

    
242

    
243
/*******************************************************************/
244
int main(void);
245
int main(void)
246
{
247
    Sine sine;
248

    
249
    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
250
    
251
    ScopedPaHandler paInit;
252
    if( paInit.result() != paNoError ) goto error;
253

    
254
    if (sine.open(Pa_GetDefaultOutputDevice()))
255
    {
256
        if (sine.start())
257
        {
258
            printf("Play for %d seconds.\n", NUM_SECONDS );
259
            Pa_Sleep( NUM_SECONDS * 1000 );
260

    
261
            sine.stop();
262
        }
263

    
264
        sine.close();
265
    }
266

    
267
    printf("Test finished.\n");
268
    return paNoError;
269

    
270
error:
271
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
272
    fprintf( stderr, "Error number: %d\n", paInit.result() );
273
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( paInit.result() ) );
274
    return 1;
275
}