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 / test / patest_maxsines.c @ 162:d43aab368df9

History | View | Annotate | Download (7.4 KB)

1
/** @file patest_maxsines.c
2
        @ingroup test_src
3
        @brief How many sine waves can we calculate and play in less than 80% CPU Load.
4
        @author Ross Bencina <rossb@audiomulch.com>
5
        @author Phil Burk <philburk@softsynth.com>
6
*/
7
/*
8
 * $Id$
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

    
45
#include <stdio.h>
46
#include <math.h>
47
#include "portaudio.h"
48

    
49
#define MAX_SINES     (2000)
50
#define MAX_USAGE     (0.5)
51
#define SAMPLE_RATE   (44100)
52
#define FREQ_TO_PHASE_INC(freq)   (freq/(float)SAMPLE_RATE)
53

    
54
#define MIN_PHASE_INC  FREQ_TO_PHASE_INC(200.0f)
55
#define MAX_PHASE_INC  (MIN_PHASE_INC * (1 << 5))
56

    
57
#define FRAMES_PER_BUFFER  (512)
58
#ifndef M_PI
59
#define M_PI  (3.14159265)
60
#endif
61
#define TWOPI (M_PI * 2.0)
62

    
63
#define TABLE_SIZE   (1024)
64

    
65
typedef struct paTestData
66
{
67
    int numSines;
68
    float sine[TABLE_SIZE + 1]; /* add one for guard point for interpolation */
69
    float phases[MAX_SINES];
70
}
71
paTestData;
72

    
73
/* Convert phase between 0.0 and 1.0 to sine value
74
 * using linear interpolation.
75
 */
76
float LookupSine( paTestData *data, float phase );
77
float LookupSine( paTestData *data, float phase )
78
{
79
    float fIndex = phase*TABLE_SIZE;
80
    int   index = (int) fIndex;
81
    float fract = fIndex - index;
82
    float lo = data->sine[index];
83
    float hi = data->sine[index+1];
84
    float val = lo + fract*(hi-lo);
85
    return val;
86
}
87

    
88
/* This routine will be called by the PortAudio engine when audio is needed.
89
** It may called at interrupt level on some machines so don't do anything
90
** that could mess up the system like calling malloc() or free().
91
*/
92
static int patestCallback(const void*                     inputBuffer,
93
                          void*                           outputBuffer,
94
                          unsigned long                   framesPerBuffer,
95
                          const PaStreamCallbackTimeInfo* timeInfo,
96
                          PaStreamCallbackFlags           statusFlags,
97
                          void*                           userData )
98
{
99
    paTestData *data = (paTestData*)userData;
100
    float *out = (float*)outputBuffer;
101
    float outSample;
102
    float scaler;
103
    int numForScale;
104
    unsigned long i;
105
    int j;
106
    int finished = 0;
107
    (void) inputBuffer; /* Prevent unused argument warning. */
108

    
109
    /* Determine amplitude scaling factor */
110
    numForScale = data->numSines;
111
    if( numForScale < 8 ) numForScale = 8;  /* prevent pops at beginning */
112
    scaler = 1.0f / numForScale;
113
    
114
    for( i=0; i<framesPerBuffer; i++ )
115
    {
116
        float output = 0.0;
117
        float phaseInc = MIN_PHASE_INC;
118
        float phase;
119
        for( j=0; j<data->numSines; j++ )
120
        {
121
            /* Advance phase of next oscillator. */
122
            phase = data->phases[j];
123
            phase += phaseInc;
124
            if( phase >= 1.0 ) phase -= 1.0;
125

    
126
            output += LookupSine(data, phase); 
127
            data->phases[j] = phase;
128
            
129
            phaseInc *= 1.02f;
130
            if( phaseInc > MAX_PHASE_INC ) phaseInc = MIN_PHASE_INC;
131
        }
132

    
133
        outSample = (float) (output * scaler);
134
        *out++ = outSample; /* Left */
135
        *out++ = outSample; /* Right */
136
    }
137
    return finished;
138
}
139

    
140
/*******************************************************************/
141
int main(void);
142
int main(void)
143
{
144
        int                 i;
145
    PaStream*           stream;
146
    PaStreamParameters  outputParameters;
147
    PaError             err;
148
    paTestData          data = {0};
149
    double              load;
150

    
151
    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
152

    
153
    /* initialise sinusoidal wavetable */
154
    for( i=0; i<TABLE_SIZE; i++ )
155
    {
156
        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
157
    }
158
    data.sine[TABLE_SIZE] = data.sine[0]; /* set guard point */
159

    
160
    err = Pa_Initialize();
161
    if( err != paNoError )
162
        goto error;
163
    outputParameters.device                    = Pa_GetDefaultOutputDevice(); /* Default output device. */
164
    if (outputParameters.device == paNoDevice) {
165
      fprintf(stderr,"Error: No default output device.\n");
166
      goto error;
167
    }
168
    outputParameters.channelCount              = 2;                           /* Stereo output. */
169
    outputParameters.sampleFormat              = paFloat32;                   /* 32 bit floating point output. */
170
    outputParameters.hostApiSpecificStreamInfo = NULL;
171
    outputParameters.suggestedLatency          = Pa_GetDeviceInfo(outputParameters.device)
172
                                                 ->defaultHighOutputLatency;
173
    err = Pa_OpenStream(&stream,
174
                        NULL,               /* no input */
175
                        &outputParameters,
176
                        SAMPLE_RATE,
177
                        FRAMES_PER_BUFFER,
178
                        paClipOff,          /* No out of range samples should occur. */
179
                        patestCallback,
180
                        &data);
181
    if( err != paNoError )
182
        goto error;
183

    
184
    err = Pa_StartStream( stream );
185
    if( err != paNoError )
186
        goto error;
187

    
188
    /* Play an increasing number of sine waves until we hit MAX_USAGE */
189
    do  {
190
        data.numSines += 10;
191
        Pa_Sleep(200);
192
        load = Pa_GetStreamCpuLoad(stream);
193
        printf("numSines = %d, CPU load = %f\n", data.numSines, load );
194
        fflush(stdout);
195
        } while((load < MAX_USAGE) && (data.numSines < MAX_SINES));
196

    
197
    Pa_Sleep(2000);     /* Stay for 2 seconds at max CPU. */
198

    
199
    err = Pa_StopStream( stream );
200
    if( err != paNoError )
201
        goto error;
202

    
203
    err = Pa_CloseStream( stream );
204
    if( err != paNoError )
205
        goto error;
206

    
207
    Pa_Terminate();
208
    printf("Test finished.\n");
209
    return err;
210
error:
211
    Pa_Terminate();
212
    fprintf( stderr, "An error occured while using the portaudio stream\n" );
213
    fprintf( stderr, "Error number: %d\n", err );
214
    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
215
    return err;
216
}