~ubuntu-branches/ubuntu/gutsy/audacity/gutsy-backports

« back to all changes in this revision

Viewing changes to lib-src/portaudio-v19/test/patest_stop.c

  • Committer: Bazaar Package Importer
  • Author(s): John Dong
  • Date: 2008-02-18 21:58:19 UTC
  • mfrom: (13.1.2 hardy)
  • Revision ID: james.westby@ubuntu.com-20080218215819-tmbcf1rx238r8gdv
Tags: 1.3.4-1.1ubuntu1~gutsy1
Automated backport upload; no source changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/** @file patest_stop.c
2
 
        @ingroup test_src
3
 
        @brief Test different ways of stopping audio.
4
 
 
5
 
        Test the three ways of stopping audio:
6
 
                - calling Pa_StopStream(),
7
 
                - calling Pa_AbortStream(),
8
 
                - and returning a 1 from the callback function.
9
 
 
10
 
        A long latency is set up so that you can hear the difference.
11
 
        Then a simple 8 note sequence is repeated twice.
12
 
        The program will print what you should hear.
13
 
 
14
 
        @author Phil Burk <philburk@softsynth.com>
15
 
*/
16
 
/*
17
 
 * $Id: patest_stop.c,v 1.2 2006/09/23 18:42:52 llucius Exp $
18
 
 *
19
 
 * This program uses the PortAudio Portable Audio Library.
20
 
 * For more information see: http://www.portaudio.com
21
 
 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
22
 
 *
23
 
 * Permission is hereby granted, free of charge, to any person obtaining
24
 
 * a copy of this software and associated documentation files
25
 
 * (the "Software"), to deal in the Software without restriction,
26
 
 * including without limitation the rights to use, copy, modify, merge,
27
 
 * publish, distribute, sublicense, and/or sell copies of the Software,
28
 
 * and to permit persons to whom the Software is furnished to do so,
29
 
 * subject to the following conditions:
30
 
 *
31
 
 * The above copyright notice and this permission notice shall be
32
 
 * included in all copies or substantial portions of the Software.
33
 
 *
34
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
35
 
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
36
 
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
37
 
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
38
 
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
39
 
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
40
 
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
41
 
 */
42
 
 
43
 
/*
44
 
 * The text above constitutes the entire PortAudio license; however, 
45
 
 * the PortAudio community also makes the following non-binding requests:
46
 
 *
47
 
 * Any person wishing to distribute modifications to the Software is
48
 
 * requested to send the modifications to the original developer so that
49
 
 * they can be incorporated into the canonical version. It is also 
50
 
 * requested that these non-binding requests be included along with the 
51
 
 * license above.
52
 
 */
53
 
#include <stdio.h>
54
 
#include <math.h>
55
 
#include "portaudio.h"
56
 
 
57
 
#define OUTPUT_DEVICE       (Pa_GetDefaultOutputDevice())
58
 
#define SLEEP_DUR           (200)
59
 
#define SAMPLE_RATE         (44100)
60
 
#define FRAMES_PER_BUFFER   (256)
61
 
#define LATENCY_SECONDS     (3.f)
62
 
#define FRAMES_PER_NOTE     (SAMPLE_RATE/2)
63
 
#define MAX_REPEATS         (2)
64
 
#define FUNDAMENTAL         (400.0f / SAMPLE_RATE)
65
 
#define NOTE_0              (FUNDAMENTAL * 1.0f / 1.0f)
66
 
#define NOTE_1              (FUNDAMENTAL * 5.0f / 4.0f)
67
 
#define NOTE_2              (FUNDAMENTAL * 4.0f / 3.0f)
68
 
#define NOTE_3              (FUNDAMENTAL * 3.0f / 2.0f)
69
 
#define NOTE_4              (FUNDAMENTAL * 2.0f / 1.0f)
70
 
#define MODE_FINISH    (0)
71
 
#define MODE_STOP      (1)
72
 
#define MODE_ABORT     (2)
73
 
#ifndef M_PI
74
 
#define M_PI  (3.14159265)
75
 
#endif
76
 
#define TABLE_SIZE   (400)
77
 
 
78
 
typedef struct
79
 
{
80
 
    float  waveform[TABLE_SIZE + 1]; /* Add one for guard point for interpolation. */
81
 
    float  phase_increment;
82
 
    float  phase;
83
 
    float *tune;
84
 
    int    notesPerTune;
85
 
    int    frameCounter;
86
 
    int    noteCounter;
87
 
    int    repeatCounter;
88
 
    PaTime outTime;
89
 
    int    stopMode;
90
 
    int    done;
91
 
}
92
 
paTestData;
93
 
 
94
 
/************* Prototypes *****************************/
95
 
int TestStopMode( paTestData *data );
96
 
float LookupWaveform( paTestData *data, float phase );
97
 
 
98
 
/******************************************************
99
 
 * Convert phase between 0.0 and 1.0 to waveform value 
100
 
 * using linear interpolation.
101
 
 */
102
 
float LookupWaveform( paTestData *data, float phase )
103
 
{
104
 
    float fIndex = phase*TABLE_SIZE;
105
 
    int   index = (int) fIndex;
106
 
    float fract = fIndex - index;
107
 
    float lo = data->waveform[index];
108
 
    float hi = data->waveform[index+1];
109
 
    float val = lo + fract*(hi-lo);
110
 
    return val;
111
 
}
112
 
 
113
 
/* This routine will be called by the PortAudio engine when audio is needed.
114
 
** It may called at interrupt level on some machines so don't do anything
115
 
** that could mess up the system like calling malloc() or free().
116
 
*/
117
 
static int patestCallback( const void *inputBuffer, void *outputBuffer,
118
 
                            unsigned long framesPerBuffer,
119
 
                            const PaStreamCallbackTimeInfo* timeInfo,
120
 
                            PaStreamCallbackFlags statusFlags,
121
 
                            void *userData )
122
 
{
123
 
    paTestData *data = (paTestData*)userData;
124
 
    float *out = (float*)outputBuffer;
125
 
    float value;
126
 
    unsigned int i = 0;
127
 
    int finished = paContinue;
128
 
 
129
 
    (void) inputBuffer;     /* Prevent unused variable warnings. */
130
 
    (void) timeInfo;
131
 
    (void) statusFlags;
132
 
 
133
 
 
134
 
    /* data->outTime = outTime; */
135
 
    
136
 
    if( !data->done )
137
 
    {
138
 
        for( i=0; i<framesPerBuffer; i++ )
139
 
        {
140
 
            /* Are we done with this note? */
141
 
            if( data->frameCounter >= FRAMES_PER_NOTE )
142
 
            {
143
 
                data->noteCounter += 1;
144
 
                data->frameCounter = 0;
145
 
                /* Are we done with this tune? */
146
 
                if( data->noteCounter >= data->notesPerTune )
147
 
                {
148
 
                    data->noteCounter = 0;
149
 
                    data->repeatCounter += 1;
150
 
                    /* Are we totally done? */
151
 
                    if( data->repeatCounter >= MAX_REPEATS )
152
 
                    {
153
 
                        data->done = 1;
154
 
                        if( data->stopMode == MODE_FINISH )
155
 
                        {
156
 
                            finished = paComplete;
157
 
                            break;
158
 
                        }
159
 
                    }
160
 
                }
161
 
                data->phase_increment = data->tune[data->noteCounter];
162
 
            }
163
 
            value = LookupWaveform(data, data->phase);
164
 
            *out++ = value;  /* left */
165
 
            *out++ = value;  /* right */
166
 
            data->phase += data->phase_increment;
167
 
            if( data->phase >= 1.0f ) data->phase -= 1.0f;
168
 
 
169
 
            data->frameCounter += 1;
170
 
        }
171
 
    }
172
 
    /* zero remainder of final buffer */
173
 
    for( ; i<framesPerBuffer; i++ )
174
 
    {
175
 
        *out++ = 0; /* left */
176
 
        *out++ = 0; /* right */
177
 
    }
178
 
    return finished;
179
 
}
180
 
/*******************************************************************/
181
 
int main(void);
182
 
int main(void)
183
 
{
184
 
    paTestData data;
185
 
    int i;
186
 
    float simpleTune[] = { NOTE_0, NOTE_1, NOTE_2, NOTE_3, NOTE_4, NOTE_3, NOTE_2, NOTE_1 };
187
 
    
188
 
    printf("PortAudio Test: play song and test stopping. ask for %f seconds latency\n", LATENCY_SECONDS );
189
 
    /* initialise sinusoidal wavetable */
190
 
    for( i=0; i<TABLE_SIZE; i++ )
191
 
    {
192
 
        data.waveform[i] = (float) (
193
 
                               (0.2 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. )) +
194
 
                               (0.2 * sin( ((double)(3*i)/(double)TABLE_SIZE) * M_PI * 2. )) +
195
 
                               (0.1 * sin( ((double)(5*i)/(double)TABLE_SIZE) * M_PI * 2. ))
196
 
                           );
197
 
    }
198
 
    data.waveform[TABLE_SIZE] = data.waveform[0]; /* Set guard point. */
199
 
    data.tune = &simpleTune[0];
200
 
    data.notesPerTune = sizeof(simpleTune) / sizeof(float);
201
 
 
202
 
    printf("Test MODE_FINISH - callback returns 1.\n");
203
 
    printf("Should hear entire %d note tune repeated twice.\n", data.notesPerTune);
204
 
    data.stopMode = MODE_FINISH;
205
 
    if( TestStopMode( &data ) != paNoError )
206
 
    {
207
 
        printf("Test of MODE_FINISH failed!\n");
208
 
        goto error;
209
 
    }
210
 
 
211
 
    printf("Test MODE_STOP - stop when song is done.\n");
212
 
    printf("Should hear entire %d note tune repeated twice.\n", data.notesPerTune);
213
 
    data.stopMode = MODE_STOP;
214
 
    if( TestStopMode( &data ) != paNoError )
215
 
    {
216
 
        printf("Test of MODE_STOP failed!\n");
217
 
        goto error;
218
 
    }
219
 
 
220
 
    printf("Test MODE_ABORT - abort immediately.\n");
221
 
    printf("Should hear last repetition cut short by %f seconds.\n", LATENCY_SECONDS);
222
 
    data.stopMode = MODE_ABORT;
223
 
    if( TestStopMode( &data ) != paNoError )
224
 
    {
225
 
        printf("Test of MODE_ABORT failed!\n");
226
 
        goto error;
227
 
    }
228
 
 
229
 
    return 0;
230
 
 
231
 
error:
232
 
    return 1;
233
 
}
234
 
 
235
 
int TestStopMode( paTestData *data )
236
 
{
237
 
    PaStreamParameters outputParameters;
238
 
    PaStream *stream;
239
 
    PaError err;
240
 
    
241
 
    data->done = 0;
242
 
    data->phase = 0.0;
243
 
    data->frameCounter = 0;
244
 
    data->noteCounter = 0;
245
 
    data->repeatCounter = 0;
246
 
    data->phase_increment = data->tune[data->noteCounter];
247
 
    
248
 
    err = Pa_Initialize();
249
 
    if( err != paNoError ) goto error;
250
 
 
251
 
    outputParameters.device = OUTPUT_DEVICE;
252
 
    outputParameters.channelCount = 2;          /* stereo output */
253
 
    outputParameters.sampleFormat = paFloat32;  /* 32 bit floating point output */
254
 
    outputParameters.suggestedLatency = LATENCY_SECONDS;
255
 
    outputParameters.hostApiSpecificStreamInfo = NULL;
256
 
    
257
 
    err = Pa_OpenStream(
258
 
              &stream,
259
 
              NULL, /* no input */
260
 
              &outputParameters,
261
 
              SAMPLE_RATE,
262
 
              FRAMES_PER_BUFFER,            /* frames per buffer */
263
 
              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
264
 
              patestCallback,
265
 
              data );
266
 
    if( err != paNoError ) goto error;
267
 
 
268
 
    err = Pa_StartStream( stream );
269
 
    if( err != paNoError ) goto error;
270
 
 
271
 
    if( data->stopMode == MODE_FINISH )
272
 
    {
273
 
        while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
274
 
        {
275
 
            /*printf("outTime = %g, note# = %d, repeat# = %d\n", data->outTime,
276
 
             data->noteCounter, data->repeatCounter  );
277
 
            fflush(stdout); */
278
 
            Pa_Sleep( SLEEP_DUR );
279
 
        }
280
 
        if( err < 0 ) goto error;
281
 
    }
282
 
    else
283
 
    {
284
 
        while( data->repeatCounter < MAX_REPEATS )
285
 
        {
286
 
            /*printf("outTime = %g, note# = %d, repeat# = %d\n", data->outTime,
287
 
             data->noteCounter, data->repeatCounter  );
288
 
            fflush(stdout); */
289
 
            Pa_Sleep( SLEEP_DUR );
290
 
        }
291
 
    }
292
 
 
293
 
    if( data->stopMode == MODE_ABORT )
294
 
    {
295
 
        printf("Call Pa_AbortStream()\n");
296
 
        err = Pa_AbortStream( stream );
297
 
    }
298
 
    else
299
 
    {
300
 
        printf("Call Pa_StopStream()\n");
301
 
        err = Pa_StopStream( stream );
302
 
    }
303
 
    if( err != paNoError ) goto error;
304
 
 
305
 
    printf("Call Pa_CloseStream()\n"); fflush(stdout);
306
 
    err = Pa_CloseStream( stream );
307
 
    if( err != paNoError ) goto error;
308
 
 
309
 
    Pa_Terminate();
310
 
    printf("Test finished.\n");
311
 
 
312
 
    return err;
313
 
 
314
 
error:
315
 
    Pa_Terminate();
316
 
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
317
 
    fprintf( stderr, "Error number: %d\n", err );
318
 
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
319
 
    return err;
320
 
}