~ubuntu-branches/ubuntu/trusty/sflphone/trusty

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.0.1/third_party/portaudio/src/common/pa_skeleton.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (4.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20140128182336-jrsv0k9u6cawc068
Tags: 1.3.0-1
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * $Id: pa_skeleton.c 1339 2008-02-15 07:50:33Z rossb $
3
 
 * Portable Audio I/O Library skeleton implementation
4
 
 * demonstrates how to use the common functions to implement support
5
 
 * for a host API
6
 
 *
7
 
 * Based on the Open Source API proposed by Ross Bencina
8
 
 * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
9
 
 *
10
 
 * Permission is hereby granted, free of charge, to any person obtaining
11
 
 * a copy of this software and associated documentation files
12
 
 * (the "Software"), to deal in the Software without restriction,
13
 
 * including without limitation the rights to use, copy, modify, merge,
14
 
 * publish, distribute, sublicense, and/or sell copies of the Software,
15
 
 * and to permit persons to whom the Software is furnished to do so,
16
 
 * subject to the following conditions:
17
 
 *
18
 
 * The above copyright notice and this permission notice shall be
19
 
 * included in all copies or substantial portions of the Software.
20
 
 *
21
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22
 
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
 
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24
 
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
25
 
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
26
 
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27
 
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
 
 */
29
 
 
30
 
/*
31
 
 * The text above constitutes the entire PortAudio license; however,
32
 
 * the PortAudio community also makes the following non-binding requests:
33
 
 *
34
 
 * Any person wishing to distribute modifications to the Software is
35
 
 * requested to send the modifications to the original developer so that
36
 
 * they can be incorporated into the canonical version. It is also
37
 
 * requested that these non-binding requests be included along with the
38
 
 * license above.
39
 
 */
40
 
 
41
 
/** @file
42
 
 @ingroup common_src
43
 
 
44
 
 @brief Skeleton implementation of support for a host API.
45
 
 
46
 
 This file is provided as a starting point for implementing support for
47
 
 a new host API. It provides examples of how the common code can be used.
48
 
 
49
 
 @note IMPLEMENT ME comments are used to indicate functionality
50
 
 which much be customised for each implementation.
51
 
*/
52
 
 
53
 
 
54
 
#include <string.h> /* strlen() */
55
 
 
56
 
#include "pa_util.h"
57
 
#include "pa_allocation.h"
58
 
#include "pa_hostapi.h"
59
 
#include "pa_stream.h"
60
 
#include "pa_cpuload.h"
61
 
#include "pa_process.h"
62
 
 
63
 
 
64
 
/* prototypes for functions declared in this file */
65
 
 
66
 
#ifdef __cplusplus
67
 
extern "C"
68
 
{
69
 
#endif /* __cplusplus */
70
 
 
71
 
PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
72
 
 
73
 
#ifdef __cplusplus
74
 
}
75
 
#endif /* __cplusplus */
76
 
 
77
 
 
78
 
static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
79
 
static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
80
 
                                  const PaStreamParameters *inputParameters,
81
 
                                  const PaStreamParameters *outputParameters,
82
 
                                  double sampleRate );
83
 
static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
84
 
                           PaStream** s,
85
 
                           const PaStreamParameters *inputParameters,
86
 
                           const PaStreamParameters *outputParameters,
87
 
                           double sampleRate,
88
 
                           unsigned long framesPerBuffer,
89
 
                           PaStreamFlags streamFlags,
90
 
                           PaStreamCallback *streamCallback,
91
 
                           void *userData );
92
 
static PaError CloseStream( PaStream* stream );
93
 
static PaError StartStream( PaStream *stream );
94
 
static PaError StopStream( PaStream *stream );
95
 
static PaError AbortStream( PaStream *stream );
96
 
static PaError IsStreamStopped( PaStream *s );
97
 
static PaError IsStreamActive( PaStream *stream );
98
 
static PaTime GetStreamTime( PaStream *stream );
99
 
static double GetStreamCpuLoad( PaStream* stream );
100
 
static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );
101
 
static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );
102
 
static signed long GetStreamReadAvailable( PaStream* stream );
103
 
static signed long GetStreamWriteAvailable( PaStream* stream );
104
 
 
105
 
 
106
 
/* IMPLEMENT ME: a macro like the following one should be used for reporting
107
 
 host errors */
108
 
#define PA_SKELETON_SET_LAST_HOST_ERROR( errorCode, errorText ) \
109
 
    PaUtil_SetLastHostErrorInfo( paInDevelopment, errorCode, errorText )
110
 
 
111
 
/* PaSkeletonHostApiRepresentation - host api datastructure specific to this implementation */
112
 
 
113
 
typedef struct
114
 
{
115
 
    PaUtilHostApiRepresentation inheritedHostApiRep;
116
 
    PaUtilStreamInterface callbackStreamInterface;
117
 
    PaUtilStreamInterface blockingStreamInterface;
118
 
 
119
 
    PaUtilAllocationGroup *allocations;
120
 
 
121
 
    /* implementation specific data goes here */
122
 
}
123
 
PaSkeletonHostApiRepresentation;  /* IMPLEMENT ME: rename this */
124
 
 
125
 
 
126
 
PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
127
 
{
128
 
    PaError result = paNoError;
129
 
    int i, deviceCount;
130
 
    PaSkeletonHostApiRepresentation *skeletonHostApi;
131
 
    PaDeviceInfo *deviceInfoArray;
132
 
 
133
 
    skeletonHostApi = (PaSkeletonHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaSkeletonHostApiRepresentation) );
134
 
    if( !skeletonHostApi )
135
 
    {
136
 
        result = paInsufficientMemory;
137
 
        goto error;
138
 
    }
139
 
 
140
 
    skeletonHostApi->allocations = PaUtil_CreateAllocationGroup();
141
 
    if( !skeletonHostApi->allocations )
142
 
    {
143
 
        result = paInsufficientMemory;
144
 
        goto error;
145
 
    }
146
 
 
147
 
    *hostApi = &skeletonHostApi->inheritedHostApiRep;
148
 
    (*hostApi)->info.structVersion = 1;
149
 
    (*hostApi)->info.type = paInDevelopment;            /* IMPLEMENT ME: change to correct type id */
150
 
    (*hostApi)->info.name = "skeleton implementation";  /* IMPLEMENT ME: change to correct name */
151
 
 
152
 
    (*hostApi)->info.defaultInputDevice = paNoDevice;  /* IMPLEMENT ME */
153
 
    (*hostApi)->info.defaultOutputDevice = paNoDevice; /* IMPLEMENT ME */
154
 
 
155
 
    (*hostApi)->info.deviceCount = 0;
156
 
 
157
 
    deviceCount = 0; /* IMPLEMENT ME */
158
 
 
159
 
    if( deviceCount > 0 )
160
 
    {
161
 
        (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
162
 
                skeletonHostApi->allocations, sizeof(PaDeviceInfo*) * deviceCount );
163
 
        if( !(*hostApi)->deviceInfos )
164
 
        {
165
 
            result = paInsufficientMemory;
166
 
            goto error;
167
 
        }
168
 
 
169
 
        /* allocate all device info structs in a contiguous block */
170
 
        deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory(
171
 
                skeletonHostApi->allocations, sizeof(PaDeviceInfo) * deviceCount );
172
 
        if( !deviceInfoArray )
173
 
        {
174
 
            result = paInsufficientMemory;
175
 
            goto error;
176
 
        }
177
 
 
178
 
        for( i=0; i < deviceCount; ++i )
179
 
        {
180
 
            PaDeviceInfo *deviceInfo = &deviceInfoArray[i];
181
 
            deviceInfo->structVersion = 2;
182
 
            deviceInfo->hostApi = hostApiIndex;
183
 
            deviceInfo->name = 0; /* IMPLEMENT ME: allocate block and copy name eg:
184
 
                deviceName = (char*)PaUtil_GroupAllocateMemory( skeletonHostApi->allocations, strlen(srcName) + 1 );
185
 
                if( !deviceName )
186
 
                {
187
 
                    result = paInsufficientMemory;
188
 
                    goto error;
189
 
                }
190
 
                strcpy( deviceName, srcName );
191
 
                deviceInfo->name = deviceName;
192
 
            */
193
 
 
194
 
            deviceInfo->maxInputChannels = 0;  /* IMPLEMENT ME */
195
 
            deviceInfo->maxOutputChannels = 0;  /* IMPLEMENT ME */
196
 
 
197
 
            deviceInfo->defaultLowInputLatency = 0.;  /* IMPLEMENT ME */
198
 
            deviceInfo->defaultLowOutputLatency = 0.;  /* IMPLEMENT ME */
199
 
            deviceInfo->defaultHighInputLatency = 0.;  /* IMPLEMENT ME */
200
 
            deviceInfo->defaultHighOutputLatency = 0.;  /* IMPLEMENT ME */
201
 
 
202
 
            deviceInfo->defaultSampleRate = 0.; /* IMPLEMENT ME */
203
 
 
204
 
            (*hostApi)->deviceInfos[i] = deviceInfo;
205
 
            ++(*hostApi)->info.deviceCount;
206
 
        }
207
 
    }
208
 
 
209
 
    (*hostApi)->Terminate = Terminate;
210
 
    (*hostApi)->OpenStream = OpenStream;
211
 
    (*hostApi)->IsFormatSupported = IsFormatSupported;
212
 
 
213
 
    PaUtil_InitializeStreamInterface( &skeletonHostApi->callbackStreamInterface, CloseStream, StartStream,
214
 
                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
215
 
                                      GetStreamTime, GetStreamCpuLoad,
216
 
                                      PaUtil_DummyRead, PaUtil_DummyWrite,
217
 
                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );
218
 
 
219
 
    PaUtil_InitializeStreamInterface( &skeletonHostApi->blockingStreamInterface, CloseStream, StartStream,
220
 
                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
221
 
                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
222
 
                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
223
 
 
224
 
    return result;
225
 
 
226
 
error:
227
 
    if( skeletonHostApi )
228
 
    {
229
 
        if( skeletonHostApi->allocations )
230
 
        {
231
 
            PaUtil_FreeAllAllocations( skeletonHostApi->allocations );
232
 
            PaUtil_DestroyAllocationGroup( skeletonHostApi->allocations );
233
 
        }
234
 
 
235
 
        PaUtil_FreeMemory( skeletonHostApi );
236
 
    }
237
 
    return result;
238
 
}
239
 
 
240
 
 
241
 
static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
242
 
{
243
 
    PaSkeletonHostApiRepresentation *skeletonHostApi = (PaSkeletonHostApiRepresentation*)hostApi;
244
 
 
245
 
    /*
246
 
        IMPLEMENT ME:
247
 
            - clean up any resources not handled by the allocation group
248
 
    */
249
 
 
250
 
    if( skeletonHostApi->allocations )
251
 
    {
252
 
        PaUtil_FreeAllAllocations( skeletonHostApi->allocations );
253
 
        PaUtil_DestroyAllocationGroup( skeletonHostApi->allocations );
254
 
    }
255
 
 
256
 
    PaUtil_FreeMemory( skeletonHostApi );
257
 
}
258
 
 
259
 
 
260
 
static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
261
 
                                  const PaStreamParameters *inputParameters,
262
 
                                  const PaStreamParameters *outputParameters,
263
 
                                  double sampleRate )
264
 
{
265
 
    int inputChannelCount, outputChannelCount;
266
 
    PaSampleFormat inputSampleFormat, outputSampleFormat;
267
 
 
268
 
    if( inputParameters )
269
 
    {
270
 
        inputChannelCount = inputParameters->channelCount;
271
 
        inputSampleFormat = inputParameters->sampleFormat;
272
 
 
273
 
        /* all standard sample formats are supported by the buffer adapter,
274
 
            this implementation doesn't support any custom sample formats */
275
 
        if( inputSampleFormat & paCustomFormat )
276
 
            return paSampleFormatNotSupported;
277
 
 
278
 
        /* unless alternate device specification is supported, reject the use of
279
 
            paUseHostApiSpecificDeviceSpecification */
280
 
 
281
 
        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
282
 
            return paInvalidDevice;
283
 
 
284
 
        /* check that input device can support inputChannelCount */
285
 
        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
286
 
            return paInvalidChannelCount;
287
 
 
288
 
        /* validate inputStreamInfo */
289
 
        if( inputParameters->hostApiSpecificStreamInfo )
290
 
            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
291
 
    }
292
 
    else
293
 
    {
294
 
        inputChannelCount = 0;
295
 
    }
296
 
 
297
 
    if( outputParameters )
298
 
    {
299
 
        outputChannelCount = outputParameters->channelCount;
300
 
        outputSampleFormat = outputParameters->sampleFormat;
301
 
 
302
 
        /* all standard sample formats are supported by the buffer adapter,
303
 
            this implementation doesn't support any custom sample formats */
304
 
        if( outputSampleFormat & paCustomFormat )
305
 
            return paSampleFormatNotSupported;
306
 
 
307
 
        /* unless alternate device specification is supported, reject the use of
308
 
            paUseHostApiSpecificDeviceSpecification */
309
 
 
310
 
        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
311
 
            return paInvalidDevice;
312
 
 
313
 
        /* check that output device can support outputChannelCount */
314
 
        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
315
 
            return paInvalidChannelCount;
316
 
 
317
 
        /* validate outputStreamInfo */
318
 
        if( outputParameters->hostApiSpecificStreamInfo )
319
 
            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
320
 
    }
321
 
    else
322
 
    {
323
 
        outputChannelCount = 0;
324
 
    }
325
 
 
326
 
    /*
327
 
        IMPLEMENT ME:
328
 
 
329
 
            - if a full duplex stream is requested, check that the combination
330
 
                of input and output parameters is supported if necessary
331
 
 
332
 
            - check that the device supports sampleRate
333
 
 
334
 
        Because the buffer adapter handles conversion between all standard
335
 
        sample formats, the following checks are only required if paCustomFormat
336
 
        is implemented, or under some other unusual conditions.
337
 
 
338
 
            - check that input device can support inputSampleFormat, or that
339
 
                we have the capability to convert from inputSampleFormat to
340
 
                a native format
341
 
 
342
 
            - check that output device can support outputSampleFormat, or that
343
 
                we have the capability to convert from outputSampleFormat to
344
 
                a native format
345
 
    */
346
 
 
347
 
 
348
 
    /* suppress unused variable warnings */
349
 
    (void) sampleRate;
350
 
 
351
 
    return paFormatIsSupported;
352
 
}
353
 
 
354
 
/* PaSkeletonStream - a stream data structure specifically for this implementation */
355
 
 
356
 
typedef struct PaSkeletonStream
357
 
{ /* IMPLEMENT ME: rename this */
358
 
    PaUtilStreamRepresentation streamRepresentation;
359
 
    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
360
 
    PaUtilBufferProcessor bufferProcessor;
361
 
 
362
 
    /* IMPLEMENT ME:
363
 
            - implementation specific data goes here
364
 
    */
365
 
    unsigned long framesPerHostCallback; /* just an example */
366
 
}
367
 
PaSkeletonStream;
368
 
 
369
 
/* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */
370
 
 
371
 
static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
372
 
                           PaStream** s,
373
 
                           const PaStreamParameters *inputParameters,
374
 
                           const PaStreamParameters *outputParameters,
375
 
                           double sampleRate,
376
 
                           unsigned long framesPerBuffer,
377
 
                           PaStreamFlags streamFlags,
378
 
                           PaStreamCallback *streamCallback,
379
 
                           void *userData )
380
 
{
381
 
    PaError result = paNoError;
382
 
    PaSkeletonHostApiRepresentation *skeletonHostApi = (PaSkeletonHostApiRepresentation*)hostApi;
383
 
    PaSkeletonStream *stream = 0;
384
 
    unsigned long framesPerHostBuffer = framesPerBuffer; /* these may not be equivalent for all implementations */
385
 
    int inputChannelCount, outputChannelCount;
386
 
    PaSampleFormat inputSampleFormat, outputSampleFormat;
387
 
    PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat;
388
 
 
389
 
 
390
 
    if( inputParameters )
391
 
    {
392
 
        inputChannelCount = inputParameters->channelCount;
393
 
        inputSampleFormat = inputParameters->sampleFormat;
394
 
 
395
 
        /* unless alternate device specification is supported, reject the use of
396
 
            paUseHostApiSpecificDeviceSpecification */
397
 
 
398
 
        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
399
 
            return paInvalidDevice;
400
 
 
401
 
        /* check that input device can support inputChannelCount */
402
 
        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
403
 
            return paInvalidChannelCount;
404
 
 
405
 
        /* validate inputStreamInfo */
406
 
        if( inputParameters->hostApiSpecificStreamInfo )
407
 
            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
408
 
 
409
 
        /* IMPLEMENT ME - establish which  host formats are available */
410
 
        hostInputSampleFormat =
411
 
            PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputSampleFormat );
412
 
    }
413
 
    else
414
 
    {
415
 
        inputChannelCount = 0;
416
 
        inputSampleFormat = hostInputSampleFormat = paInt16; /* Surpress 'uninitialised var' warnings. */
417
 
    }
418
 
 
419
 
    if( outputParameters )
420
 
    {
421
 
        outputChannelCount = outputParameters->channelCount;
422
 
        outputSampleFormat = outputParameters->sampleFormat;
423
 
 
424
 
        /* unless alternate device specification is supported, reject the use of
425
 
            paUseHostApiSpecificDeviceSpecification */
426
 
 
427
 
        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
428
 
            return paInvalidDevice;
429
 
 
430
 
        /* check that output device can support inputChannelCount */
431
 
        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
432
 
            return paInvalidChannelCount;
433
 
 
434
 
        /* validate outputStreamInfo */
435
 
        if( outputParameters->hostApiSpecificStreamInfo )
436
 
            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
437
 
 
438
 
        /* IMPLEMENT ME - establish which  host formats are available */
439
 
        hostOutputSampleFormat =
440
 
            PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputSampleFormat );
441
 
    }
442
 
    else
443
 
    {
444
 
        outputChannelCount = 0;
445
 
        outputSampleFormat = hostOutputSampleFormat = paInt16; /* Surpress 'uninitialized var' warnings. */
446
 
    }
447
 
 
448
 
    /*
449
 
        IMPLEMENT ME:
450
 
 
451
 
        ( the following two checks are taken care of by PaUtil_InitializeBufferProcessor() FIXME - checks needed? )
452
 
 
453
 
            - check that input device can support inputSampleFormat, or that
454
 
                we have the capability to convert from outputSampleFormat to
455
 
                a native format
456
 
 
457
 
            - check that output device can support outputSampleFormat, or that
458
 
                we have the capability to convert from outputSampleFormat to
459
 
                a native format
460
 
 
461
 
            - if a full duplex stream is requested, check that the combination
462
 
                of input and output parameters is supported
463
 
 
464
 
            - check that the device supports sampleRate
465
 
 
466
 
            - alter sampleRate to a close allowable rate if possible / necessary
467
 
 
468
 
            - validate suggestedInputLatency and suggestedOutputLatency parameters,
469
 
                use default values where necessary
470
 
    */
471
 
 
472
 
 
473
 
 
474
 
 
475
 
    /* validate platform specific flags */
476
 
    if( (streamFlags & paPlatformSpecificFlags) != 0 )
477
 
        return paInvalidFlag; /* unexpected platform specific flag */
478
 
 
479
 
 
480
 
    stream = (PaSkeletonStream*)PaUtil_AllocateMemory( sizeof(PaSkeletonStream) );
481
 
    if( !stream )
482
 
    {
483
 
        result = paInsufficientMemory;
484
 
        goto error;
485
 
    }
486
 
 
487
 
    if( streamCallback )
488
 
    {
489
 
        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
490
 
                                               &skeletonHostApi->callbackStreamInterface, streamCallback, userData );
491
 
    }
492
 
    else
493
 
    {
494
 
        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
495
 
                                               &skeletonHostApi->blockingStreamInterface, streamCallback, userData );
496
 
    }
497
 
 
498
 
    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
499
 
 
500
 
 
501
 
    /* we assume a fixed host buffer size in this example, but the buffer processor
502
 
        can also support bounded and unknown host buffer sizes by passing
503
 
        paUtilBoundedHostBufferSize or paUtilUnknownHostBufferSize instead of
504
 
        paUtilFixedHostBufferSize below. */
505
 
 
506
 
    result =  PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
507
 
              inputChannelCount, inputSampleFormat, hostInputSampleFormat,
508
 
              outputChannelCount, outputSampleFormat, hostOutputSampleFormat,
509
 
              sampleRate, streamFlags, framesPerBuffer,
510
 
              framesPerHostBuffer, paUtilFixedHostBufferSize,
511
 
              streamCallback, userData );
512
 
    if( result != paNoError )
513
 
        goto error;
514
 
 
515
 
 
516
 
    /*
517
 
        IMPLEMENT ME: initialise the following fields with estimated or actual
518
 
        values.
519
 
    */
520
 
    stream->streamRepresentation.streamInfo.inputLatency =
521
 
            PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor);
522
 
    stream->streamRepresentation.streamInfo.outputLatency =
523
 
            PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor);
524
 
    stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
525
 
 
526
 
 
527
 
    /*
528
 
        IMPLEMENT ME:
529
 
            - additional stream setup + opening
530
 
    */
531
 
 
532
 
    stream->framesPerHostCallback = framesPerHostBuffer;
533
 
 
534
 
    *s = (PaStream*)stream;
535
 
 
536
 
    return result;
537
 
 
538
 
error:
539
 
    if( stream )
540
 
        PaUtil_FreeMemory( stream );
541
 
 
542
 
    return result;
543
 
}
544
 
 
545
 
/*
546
 
    ExampleHostProcessingLoop() illustrates the kind of processing which may
547
 
    occur in a host implementation.
548
 
 
549
 
*/
550
 
static void ExampleHostProcessingLoop( void *inputBuffer, void *outputBuffer, void *userData )
551
 
{
552
 
    PaSkeletonStream *stream = (PaSkeletonStream*)userData;
553
 
    PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* IMPLEMENT ME */
554
 
    int callbackResult;
555
 
    unsigned long framesProcessed;
556
 
 
557
 
    PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
558
 
 
559
 
    /*
560
 
        IMPLEMENT ME:
561
 
            - generate timing information
562
 
            - handle buffer slips
563
 
    */
564
 
 
565
 
    /*
566
 
        If you need to byte swap or shift inputBuffer to convert it into a
567
 
        portaudio format, do it here.
568
 
    */
569
 
 
570
 
 
571
 
 
572
 
    PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, 0 /* IMPLEMENT ME: pass underflow/overflow flags when necessary */ );
573
 
 
574
 
    /*
575
 
        depending on whether the host buffers are interleaved, non-interleaved
576
 
        or a mixture, you will want to call PaUtil_SetInterleaved*Channels(),
577
 
        PaUtil_SetNonInterleaved*Channel() or PaUtil_Set*Channel() here.
578
 
    */
579
 
 
580
 
    PaUtil_SetInputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
581
 
    PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor,
582
 
            0, /* first channel of inputBuffer is channel 0 */
583
 
            inputBuffer,
584
 
            0 ); /* 0 - use inputChannelCount passed to init buffer processor */
585
 
 
586
 
    PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
587
 
    PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor,
588
 
            0, /* first channel of outputBuffer is channel 0 */
589
 
            outputBuffer,
590
 
            0 ); /* 0 - use outputChannelCount passed to init buffer processor */
591
 
 
592
 
    /* you must pass a valid value of callback result to PaUtil_EndBufferProcessing()
593
 
        in general you would pass paContinue for normal operation, and
594
 
        paComplete to drain the buffer processor's internal output buffer.
595
 
        You can check whether the buffer processor's output buffer is empty
596
 
        using PaUtil_IsBufferProcessorOuputEmpty( bufferProcessor )
597
 
    */
598
 
    callbackResult = paContinue;
599
 
    framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult );
600
 
 
601
 
 
602
 
    /*
603
 
        If you need to byte swap or shift outputBuffer to convert it to
604
 
        host format, do it here.
605
 
    */
606
 
 
607
 
    PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );
608
 
 
609
 
 
610
 
    if( callbackResult == paContinue )
611
 
    {
612
 
        /* nothing special to do */
613
 
    }
614
 
    else if( callbackResult == paAbort )
615
 
    {
616
 
        /* IMPLEMENT ME - finish playback immediately  */
617
 
 
618
 
        /* once finished, call the finished callback */
619
 
        if( stream->streamRepresentation.streamFinishedCallback != 0 )
620
 
            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
621
 
    }
622
 
    else
623
 
    {
624
 
        /* User callback has asked us to stop with paComplete or other non-zero value */
625
 
 
626
 
        /* IMPLEMENT ME - finish playback once currently queued audio has completed  */
627
 
 
628
 
        /* once finished, call the finished callback */
629
 
        if( stream->streamRepresentation.streamFinishedCallback != 0 )
630
 
            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
631
 
    }
632
 
}
633
 
 
634
 
 
635
 
/*
636
 
    When CloseStream() is called, the multi-api layer ensures that
637
 
    the stream has already been stopped or aborted.
638
 
*/
639
 
static PaError CloseStream( PaStream* s )
640
 
{
641
 
    PaError result = paNoError;
642
 
    PaSkeletonStream *stream = (PaSkeletonStream*)s;
643
 
 
644
 
    /*
645
 
        IMPLEMENT ME:
646
 
            - additional stream closing + cleanup
647
 
    */
648
 
 
649
 
    PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
650
 
    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
651
 
    PaUtil_FreeMemory( stream );
652
 
 
653
 
    return result;
654
 
}
655
 
 
656
 
 
657
 
static PaError StartStream( PaStream *s )
658
 
{
659
 
    PaError result = paNoError;
660
 
    PaSkeletonStream *stream = (PaSkeletonStream*)s;
661
 
 
662
 
    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
663
 
 
664
 
    /* IMPLEMENT ME, see portaudio.h for required behavior */
665
 
 
666
 
    /* suppress unused function warning. the code in ExampleHostProcessingLoop or
667
 
       something similar should be implemented to feed samples to and from the
668
 
       host after StartStream() is called.
669
 
    */
670
 
    (void) ExampleHostProcessingLoop;
671
 
 
672
 
    return result;
673
 
}
674
 
 
675
 
 
676
 
static PaError StopStream( PaStream *s )
677
 
{
678
 
    PaError result = paNoError;
679
 
    PaSkeletonStream *stream = (PaSkeletonStream*)s;
680
 
 
681
 
    /* suppress unused variable warnings */
682
 
    (void) stream;
683
 
 
684
 
    /* IMPLEMENT ME, see portaudio.h for required behavior */
685
 
 
686
 
    return result;
687
 
}
688
 
 
689
 
 
690
 
static PaError AbortStream( PaStream *s )
691
 
{
692
 
    PaError result = paNoError;
693
 
    PaSkeletonStream *stream = (PaSkeletonStream*)s;
694
 
 
695
 
    /* suppress unused variable warnings */
696
 
    (void) stream;
697
 
 
698
 
    /* IMPLEMENT ME, see portaudio.h for required behavior */
699
 
 
700
 
    return result;
701
 
}
702
 
 
703
 
 
704
 
static PaError IsStreamStopped( PaStream *s )
705
 
{
706
 
    PaSkeletonStream *stream = (PaSkeletonStream*)s;
707
 
 
708
 
    /* suppress unused variable warnings */
709
 
    (void) stream;
710
 
 
711
 
    /* IMPLEMENT ME, see portaudio.h for required behavior */
712
 
 
713
 
    return 0;
714
 
}
715
 
 
716
 
 
717
 
static PaError IsStreamActive( PaStream *s )
718
 
{
719
 
    PaSkeletonStream *stream = (PaSkeletonStream*)s;
720
 
 
721
 
    /* suppress unused variable warnings */
722
 
    (void) stream;
723
 
 
724
 
    /* IMPLEMENT ME, see portaudio.h for required behavior */
725
 
 
726
 
    return 0;
727
 
}
728
 
 
729
 
 
730
 
static PaTime GetStreamTime( PaStream *s )
731
 
{
732
 
    PaSkeletonStream *stream = (PaSkeletonStream*)s;
733
 
 
734
 
    /* suppress unused variable warnings */
735
 
    (void) stream;
736
 
 
737
 
    /* IMPLEMENT ME, see portaudio.h for required behavior*/
738
 
 
739
 
    return 0;
740
 
}
741
 
 
742
 
 
743
 
static double GetStreamCpuLoad( PaStream* s )
744
 
{
745
 
    PaSkeletonStream *stream = (PaSkeletonStream*)s;
746
 
 
747
 
    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
748
 
}
749
 
 
750
 
 
751
 
/*
752
 
    As separate stream interfaces are used for blocking and callback
753
 
    streams, the following functions can be guaranteed to only be called
754
 
    for blocking streams.
755
 
*/
756
 
 
757
 
static PaError ReadStream( PaStream* s,
758
 
                           void *buffer,
759
 
                           unsigned long frames )
760
 
{
761
 
    PaSkeletonStream *stream = (PaSkeletonStream*)s;
762
 
 
763
 
    /* suppress unused variable warnings */
764
 
    (void) buffer;
765
 
    (void) frames;
766
 
    (void) stream;
767
 
 
768
 
    /* IMPLEMENT ME, see portaudio.h for required behavior*/
769
 
 
770
 
    return paNoError;
771
 
}
772
 
 
773
 
 
774
 
static PaError WriteStream( PaStream* s,
775
 
                            const void *buffer,
776
 
                            unsigned long frames )
777
 
{
778
 
    PaSkeletonStream *stream = (PaSkeletonStream*)s;
779
 
 
780
 
    /* suppress unused variable warnings */
781
 
    (void) buffer;
782
 
    (void) frames;
783
 
    (void) stream;
784
 
 
785
 
    /* IMPLEMENT ME, see portaudio.h for required behavior*/
786
 
 
787
 
    return paNoError;
788
 
}
789
 
 
790
 
 
791
 
static signed long GetStreamReadAvailable( PaStream* s )
792
 
{
793
 
    PaSkeletonStream *stream = (PaSkeletonStream*)s;
794
 
 
795
 
    /* suppress unused variable warnings */
796
 
    (void) stream;
797
 
 
798
 
    /* IMPLEMENT ME, see portaudio.h for required behavior*/
799
 
 
800
 
    return 0;
801
 
}
802
 
 
803
 
 
804
 
static signed long GetStreamWriteAvailable( PaStream* s )
805
 
{
806
 
    PaSkeletonStream *stream = (PaSkeletonStream*)s;
807
 
 
808
 
    /* suppress unused variable warnings */
809
 
    (void) stream;
810
 
 
811
 
    /* IMPLEMENT ME, see portaudio.h for required behavior*/
812
 
 
813
 
    return 0;
814
 
}