root/portaudio/branches/V18.1/pa_tests/debug_srate.c

Revision 165, 8.2 KB (checked in by philburk, 8 years ago)

Demonstrate bug with Terratect where stream sample rates change!

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * $Id$
3 * debug_record_reuse.c
4 * Record input into an array.
5 * Save array to a file.
6 * Based on patest_record.c but with various ugly debug hacks thrown in.
7 * Loop twice and reuse same streams.
8 *
9 * Author: Phil Burk  http://www.softsynth.com
10 *
11 * This program uses the PortAudio Portable Audio Library.
12 * For more information see: http://www.portaudio.com
13 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
14 *
15 * Permission is hereby granted, free of charge, to any person obtaining
16 * a copy of this software and associated documentation files
17 * (the "Software"), to deal in the Software without restriction,
18 * including without limitation the rights to use, copy, modify, merge,
19 * publish, distribute, sublicense, and/or sell copies of the Software,
20 * and to permit persons to whom the Software is furnished to do so,
21 * subject to the following conditions:
22 *
23 * The above copyright notice and this permission notice shall be
24 * included in all copies or substantial portions of the Software.
25 *
26 * Any person wishing to distribute modifications to the Software is
27 * requested to send the modifications to the original developer so that
28 * they can be incorporated into the canonical version.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
31 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
33 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
34 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
35 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 *
38 */
39#include <stdio.h>
40#include <stdlib.h>
41#include <memory.h>
42#include "portaudio.h"
43
44#define EWS88MT_12_REC     (1)
45#define EWS88MT_12_PLAY   (10)
46#define SBLIVE_REC         (2)
47#define SBLIVE_PLAY       (11)
48
49#if 0
50#define INPUT_DEVICE_ID    Pa_GetDefaultInputDeviceID()
51#define OUTPUT_DEVICE_ID   Pa_GetDefaultOutputDeviceID()
52#else
53#define INPUT_DEVICE_ID    (EWS88MT_12_REC)
54#define OUTPUT_DEVICE_ID   (SBLIVE_PLAY)
55#endif
56
57#define INPUT_SAMPLE_RATE     (22050.0)
58#define OUTPUT_SAMPLE_RATE    (22050.0)
59#define NUM_SECONDS               (4)
60#define SLEEP_DUR_MSEC         (1000)
61#define FRAMES_PER_BUFFER        (64)
62#define NUM_REC_BUFS              (0)
63#define SAMPLES_PER_FRAME         (2)
64
65#define PA_SAMPLE_TYPE  paInt16
66typedef short SAMPLE;
67
68typedef struct
69{
70    long             frameIndex;  /* Index into sample array. */
71}
72paTestData;
73
74/* This routine will be called by the PortAudio engine when audio is needed.
75** It may be called at interrupt level on some machines so don't do anything
76** that could mess up the system like calling malloc() or free().
77*/
78static int recordCallback( void *inputBuffer, void *outputBuffer,
79                           unsigned long framesPerBuffer,
80                           PaTimestamp outTime, void *userData )
81{
82    paTestData *data = (paTestData *) userData;
83    (void) outputBuffer; /* Prevent unused variable warnings. */
84    (void) outTime;
85
86    if( inputBuffer != NULL )
87    {
88        data->frameIndex += framesPerBuffer;
89    }
90    return 0;
91}
92
93/* This routine will be called by the PortAudio engine when audio is needed.
94** It may be called at interrupt level on some machines so don't do anything
95** that could mess up the system like calling malloc() or free().
96*/
97static int playCallback( void *inputBuffer, void *outputBuffer,
98                         unsigned long framesPerBuffer,
99                         PaTimestamp outTime, void *userData )
100{
101    paTestData *data = (paTestData *) userData;
102    (void) inputBuffer; /* Prevent unused variable warnings. */
103    (void) outTime;
104
105    if( outputBuffer != NULL )
106    {
107        data->frameIndex += framesPerBuffer;
108    }
109    return 0;
110}
111
112/****************************************************************/
113PaError MeasureStreamRate( PortAudioStream *stream, paTestData *dataPtr, double *ratePtr )
114{
115    PaError    err;
116    int        i;
117    int        totalFrames = 0;
118    int        totalMSec = 0;
119
120    dataPtr->frameIndex = 0;
121
122    err = Pa_StartStream( stream );
123    if( err != paNoError ) goto error;
124
125    for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ )
126    {
127        int delta, endIndex;
128
129        int startIndex = dataPtr->frameIndex;
130        Pa_Sleep(SLEEP_DUR_MSEC);
131        endIndex = dataPtr->frameIndex;
132
133        delta = endIndex - startIndex;
134        totalFrames += delta;
135        totalMSec += SLEEP_DUR_MSEC;
136
137        printf("index = %d, delta = %d\n", endIndex, delta ); fflush(stdout);
138    }
139
140    err = Pa_StopStream( stream );
141    if( err != paNoError ) goto error;
142
143    *ratePtr = (totalFrames * 1000.0) / totalMSec;
144
145error:
146    return err;
147}
148
149void ReportRate( double measuredRate, double expectedRate )
150{
151    double error;
152
153    error = (measuredRate - expectedRate) / expectedRate;
154    error = (error < 0 ) ? -error : error;
155
156    printf("Measured rate = %6.1f, expected rate = %6.1f\n",
157            measuredRate, expectedRate );
158    if( error > 0.1 )
159    {
160        printf("ERROR: unexpected rate! ---------------------   ERROR!\n");
161    }
162    else
163    {
164        printf("SUCCESS: rate within tolerance!\n");
165    }
166}
167
168/*******************************************************************/
169int main(void);
170int main(void)
171{
172    PaError    err;
173    paTestData data = { 0 };
174    long       i;
175    double     rate;
176    const    PaDeviceInfo *pdi;
177
178    PortAudioStream *outputStream;
179    PortAudioStream *inputStream;
180
181    err = Pa_Initialize();
182    if( err != paNoError ) goto error;
183
184
185    pdi = Pa_GetDeviceInfo( INPUT_DEVICE_ID );
186    printf("Input device  = %s\n", pdi->name );
187    pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE_ID );
188    printf("Output device = %s\n", pdi->name );
189
190/* Open input stream. */
191    err = Pa_OpenStream(
192              &inputStream,
193              INPUT_DEVICE_ID,
194              SAMPLES_PER_FRAME,               /* stereo input */
195              PA_SAMPLE_TYPE,
196              NULL,
197              paNoDevice,
198              0,
199              PA_SAMPLE_TYPE,
200              NULL,
201              INPUT_SAMPLE_RATE,
202              FRAMES_PER_BUFFER,            /* frames per buffer */
203              NUM_REC_BUFS,               /* number of buffers, if zero then use default minimum */
204              paClipOff,       /* we won't output out of range samples so don't bother clipping them */
205              recordCallback,
206              &data );
207    if( err != paNoError ) goto error;
208
209    err = Pa_OpenStream(
210              &outputStream,
211              paNoDevice,
212              0,               /* NO input */
213              PA_SAMPLE_TYPE,
214              NULL,
215              OUTPUT_DEVICE_ID,
216              SAMPLES_PER_FRAME,               /* stereo output */
217              PA_SAMPLE_TYPE,
218              NULL,
219              OUTPUT_SAMPLE_RATE,
220              FRAMES_PER_BUFFER,            /* frames per buffer */
221              0,               /* number of buffers, if zero then use default minimum */
222              paClipOff,       /* we won't output out of range samples so don't bother clipping them */
223              playCallback,
224              &data );
225    if( err != paNoError ) goto error;
226
227/* Record and playback multiple times. */
228    for( i=0; i<2; i++ )
229    {
230        printf("Measuring INPUT ------------------------- \n");
231        err = MeasureStreamRate( inputStream, &data, &rate );
232        if( err != paNoError ) goto error;
233        ReportRate( rate, INPUT_SAMPLE_RATE );
234
235        printf("Measuring OUTPUT ------------------------- \n");
236        err = MeasureStreamRate( outputStream, &data, &rate );
237        if( err != paNoError ) goto error;
238        ReportRate( rate, OUTPUT_SAMPLE_RATE );
239    }
240
241/* Clean up. */
242    err = Pa_CloseStream( inputStream );
243    if( err != paNoError ) goto error;
244
245    err = Pa_CloseStream( outputStream );
246    if( err != paNoError ) goto error;
247
248    if( err != paNoError ) goto error;
249
250    Pa_Terminate();
251   
252    printf("Test complete.\n"); fflush(stdout);
253    return 0;
254
255error:
256    Pa_Terminate();
257    fprintf( stderr, "An error occured while using the portaudio stream\n" );
258    fprintf( stderr, "Error number: %d\n", err );
259    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
260    if( err == paHostError )
261    {
262        fprintf( stderr, "Host Error number: %d\n", Pa_GetHostError() );
263    }
264    return -1;
265}
Note: See TracBrowser for help on using the browser.