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

« back to all changes in this revision

Viewing changes to lib-src/portaudio-v19/src/hostapi/oss/pa_unix_oss.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
1
/*
2
 
 * $Id: pa_unix_oss.c,v 1.3 2006/10/02 00:29:04 llucius Exp $
 
2
 * $Id: pa_unix_oss.c,v 1.7 2007/08/16 20:45:36 richardash1981 Exp $
3
3
 * PortAudio Portable Real-Time Audio Library
4
4
 * Latest Version at: http://www.portaudio.com
5
5
 * OSS implementation by:
32
32
 */
33
33
 
34
34
/*
35
 
 * The text above constitutes the entire PortAudio license; however, 
 
35
 * The text above constitutes the entire PortAudio license; however,
36
36
 * the PortAudio community also makes the following non-binding requests:
37
37
 *
38
38
 * Any person wishing to distribute modifications to the Software is
39
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 
 
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
42
 * license above.
43
43
 */
44
44
 
45
45
/**
46
46
 @file
47
 
 @ingroup hostaip_src
 
47
 @ingroup hostapi_src
48
48
*/
49
49
 
50
50
#include <stdio.h>
63
63
#include <limits.h>
64
64
#include <semaphore.h>
65
65
 
66
 
#ifdef __FreeBSD__
 
66
#ifdef HAVE_SYS_SOUNDCARD_H
67
67
# include <sys/soundcard.h>
68
68
# define DEVICE_NAME_BASE            "/dev/dsp"
69
 
#elif defined __linux__
 
69
#elif defined(HAVE_LINUX_SOUNDCARD_H)
70
70
# include <linux/soundcard.h>
71
71
# define DEVICE_NAME_BASE            "/dev/dsp"
72
 
#else
 
72
#elif defined(HAVE_MACHINE_SOUNDCARD_H)
73
73
# include <machine/soundcard.h> /* JH20010905 */
74
74
# define DEVICE_NAME_BASE            "/dev/audio"
 
75
#else
 
76
# error No sound card header file
75
77
#endif
76
78
 
77
79
#include "portaudio.h"
82
84
#include "pa_cpuload.h"
83
85
#include "pa_process.h"
84
86
#include "pa_unix_util.h"
 
87
#include "pa_debugprint.h"
85
88
 
86
89
static int sysErr_;
87
90
static pthread_t mainThread_;
111
114
 */
112
115
static int Get_AFMT_S16_NE( void )
113
116
{
114
 
    long testData = 1; 
 
117
    long testData = 1;
115
118
    char *ptr = (char *) &testData;
116
119
    int isLittle = ( *ptr == 1 ); /* Does address point to least significant byte? */
117
120
    return isLittle ? AFMT_S16_LE : AFMT_S16_BE;
276
279
            PaUtil_FreeAllAllocations( ossHostApi->allocations );
277
280
            PaUtil_DestroyAllocationGroup( ossHostApi->allocations );
278
281
        }
279
 
                
 
282
 
280
283
        PaUtil_FreeMemory( ossHostApi );
281
284
    }
282
285
    return result;
287
290
        PaTime defaultHighOutputLatency, double defaultSampleRate, PaUtilAllocationGroup *allocations  )
288
291
{
289
292
    PaError result = paNoError;
290
 
    
 
293
 
291
294
    deviceInfo->structVersion = 2;
292
295
    if( allocations )
293
296
    {
382
385
        {
383
386
            maxNumChannels = (stereo) ? 2 : 1;
384
387
        }
385
 
        PA_DEBUG(( "%s: use SNDCTL_DSP_STEREO, maxNumChannels = %d\n", __FUNCTION__, maxNumChannels ))
 
388
        PA_DEBUG(( "%s: use SNDCTL_DSP_STEREO, maxNumChannels = %d\n", __FUNCTION__, maxNumChannels ));
386
389
    }
387
390
 
388
391
    /* During channel negotiation, the last ioctl() may have failed. This can
438
441
 
439
442
    /* douglas:
440
443
       we have to do this querying in a slightly different order. apparently
441
 
       some sound cards will give you different info based on their settins. 
 
444
       some sound cards will give you different info based on their settins.
442
445
       e.g. a card might give you stereo at 22kHz but only mono at 44kHz.
443
446
       the correct order for OSS is: format, channels, sample rate
444
447
    */
594
597
    int tempDevHandle = -1;
595
598
    int flags;
596
599
    PaSampleFormat inputSampleFormat, outputSampleFormat;
597
 
    
 
600
 
598
601
    if( inputParameters )
599
602
    {
600
603
        inputChannelCount = inputParameters->channelCount;
623
626
    {
624
627
        outputChannelCount = outputParameters->channelCount;
625
628
        outputSampleFormat = outputParameters->sampleFormat;
626
 
        
 
629
 
627
630
        /* unless alternate device specification is supported, reject the use of
628
631
            paUseHostApiSpecificDeviceSpecification */
629
632
 
659
662
       return paInvalidChannelCount;
660
663
 
661
664
    /* open the device so we can do more tests */
662
 
    
 
665
 
663
666
    if( inputChannelCount > 0 )
664
667
    {
665
668
        result = PaUtil_DeviceIndexToHostApiDeviceIndex(&device, inputParameters->device, hostApi);
675
678
 
676
679
    deviceInfo = hostApi->deviceInfos[device];
677
680
    deviceName = (char *)deviceInfo->name;
678
 
    
 
681
 
679
682
    flags = O_NONBLOCK;
680
683
    if (inputChannelCount > 0 && outputChannelCount > 0)
681
684
       flags |= O_RDWR;
693
696
 
694
697
 error:
695
698
    if( tempDevHandle >= 0 )
696
 
        close( tempDevHandle );         
 
699
        close( tempDevHandle );
697
700
 
698
701
    return result;
699
702
}
880
883
    {
881
884
        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
882
885
                                               &ossApi->blockingStreamInterface, callback, userData );
883
 
    }    
 
886
    }
884
887
 
885
888
    ENSURE_( sem_init( &stream->semaphore, 0, 0 ), paInternalError );
886
889
 
946
949
        frmts |= paInt16;
947
950
    else
948
951
        result = paSampleFormatNotSupported;
949
 
    
 
952
 
950
953
    *availableFormats = frmts;
951
954
 
952
955
error:
984
987
    int frgmt;
985
988
    int numBufs;
986
989
    int bytesPerBuf;
987
 
    double bufSz;
 
990
    unsigned long bufSz;
988
991
    unsigned long fragSz;
989
992
    audio_buf_info bufInfo;
990
993
 
996
999
         * The hardware need not respect the requested fragment size, so we may have to adapt.
997
1000
         */
998
1001
        if( framesPerBuffer == paFramesPerBufferUnspecified )
999
 
        { 
1000
 
            bufSz = component->latency * sampleRate;
 
1002
        {
 
1003
            bufSz = (unsigned long)(component->latency * sampleRate);
1001
1004
            fragSz = bufSz / 4;
1002
1005
        }
1003
1006
        else
1004
1007
        {
1005
1008
            fragSz = framesPerBuffer;
1006
 
            bufSz = component->latency * sampleRate + fragSz; /* Latency + 1 buffer */
 
1009
            bufSz = (unsigned long)(component->latency * sampleRate) + fragSz; /* Latency + 1 buffer */
1007
1010
        }
1008
1011
 
1009
1012
        PA_ENSURE( GetAvailableFormats( component, &availableFormats ) );
1010
1013
        hostFormat = PaUtil_SelectClosestAvailableFormat( availableFormats, component->userFormat );
1011
1014
 
1012
1015
        /* OSS demands at least 2 buffers, and 16 bytes per buffer */
1013
 
        numBufs = PA_MAX( bufSz / fragSz, 2 );
 
1016
        numBufs = (int)PA_MAX( bufSz / fragSz, 2 );
1014
1017
        bytesPerBuf = PA_MAX( fragSz * Pa_GetSampleSize( hostFormat ) * chans, 16 );
1015
1018
 
1016
1019
        /* The fragment parameters are encoded like this:
1040
1043
        /* reject if there's no sample rate within 1% of the one requested */
1041
1044
        if( (fabs( sampleRate - sr ) / sampleRate) > 0.01 )
1042
1045
        {
1043
 
            PA_DEBUG(("%s: Wanted %f, closest sample rate was %d\n", __FUNCTION__, sampleRate, sr ));                 
 
1046
            PA_DEBUG(("%s: Wanted %f, closest sample rate was %d\n", __FUNCTION__, sampleRate, sr ));
1044
1047
            PA_ENSURE( paInvalidSampleRate );
1045
1048
        }
1046
1049
 
1117
1120
    if( stream->capture )
1118
1121
    {
1119
1122
        PaOssStreamComponent *component = stream->capture;
1120
 
        PaOssStreamComponent_Configure( component, sampleRate, framesPerBuffer, StreamMode_In, NULL );
 
1123
        PA_ENSURE( PaOssStreamComponent_Configure( component, sampleRate, framesPerBuffer, StreamMode_In,
 
1124
                    NULL ) );
1121
1125
 
1122
1126
        assert( component->hostChannelCount > 0 );
1123
1127
        assert( component->hostFrames > 0 );
1220
1224
                return paInvalidChannelCount;
1221
1225
        }
1222
1226
    }
1223
 
    
 
1227
 
1224
1228
    /* allocate and do basic initialization of the stream structure */
1225
1229
    PA_UNLESS( stream = (PaOssStream*)PaUtil_AllocateMemory( sizeof(PaOssStream) ), paInsufficientMemory );
1226
1230
    PA_ENSURE( PaOssStream_Initialize( stream, inputParameters, outputParameters, streamCallback, userData, streamFlags, ossHostApi ) );
1228
1232
    PA_ENSURE( PaOssStream_Configure( stream, sampleRate, framesPerBuffer, &inLatency, &outLatency ) );
1229
1233
 
1230
1234
    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
1231
 
        
 
1235
 
1232
1236
    if( inputParameters )
1233
1237
    {
1234
1238
        inputHostFormat = stream->capture->hostFormat;
1350
1354
                pollCapture = 0;
1351
1355
            }
1352
1356
            */
1353
 
            else if( stream->playback ) /* Timed out, go on with playback? */ 
 
1357
            else if( stream->playback ) /* Timed out, go on with playback? */
1354
1358
            {
1355
1359
                /*PA_DEBUG(( "%s: Trying to poll again for capture frames, pollTimeout: %d\n",
1356
1360
                            __FUNCTION__, stream->pollTimeout ));*/
1461
1465
 
1462
1466
    /* Ok, we have triggered the stream */
1463
1467
    stream->triggered = 1;
1464
 
    
 
1468
 
1465
1469
error:
1466
1470
    return result;
1467
1471
}
1500
1504
    PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer );
1501
1505
 
1502
1506
    PaOssStream_Stop( stream, stream->callbackAbort );
1503
 
    
 
1507
 
1504
1508
    PA_DEBUG(( "OnExit: Stoppage\n" ));
1505
1509
 
1506
1510
    /* Eventually notify user all buffers have played */
1548
1552
    int initiateProcessing = triggered;    /* Already triggered? */
1549
1553
    PaStreamCallbackFlags cbFlags = 0;  /* We might want to keep state across iterations */
1550
1554
    PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* TODO: IMPLEMENT ME */
1551
 
    
 
1555
 
1552
1556
    /*
1553
1557
#if ( SOUND_VERSION > 0x030904 )
1554
1558
        audio_errinfo errinfo;
1555
1559
#endif
1556
1560
*/
1557
 
    
 
1561
 
1558
1562
    assert( stream );
1559
1563
 
1560
1564
    pthread_cleanup_push( &OnExit, stream );    /* Execute OnExit when exiting */
1592
1596
         */
1593
1597
        if( !initiateProcessing )
1594
1598
        {
1595
 
            PA_ENSURE( PaOssStream_WaitForFrames( stream, &framesAvail ) );  /* Wait on available frames */
 
1599
            /* Wait on available frames */
 
1600
            PA_ENSURE( PaOssStream_WaitForFrames( stream, &framesAvail ) );
1596
1601
            assert( framesAvail % stream->framesPerHostBuffer == 0 );
1597
1602
        }
1598
1603
        else
1612
1617
            if ( stream->capture )
1613
1618
            {
1614
1619
                PA_ENSURE( PaOssStreamComponent_Read( stream->capture, &frames ) );
1615
 
                assert( frames == framesAvail );
 
1620
                if( frames < framesAvail )
 
1621
                {
 
1622
                    PA_DEBUG(( "Read %lu less frames than requested\n", framesAvail - frames ));
 
1623
                    framesAvail = frames;
 
1624
                }
1616
1625
            }
1617
1626
 
1618
1627
#if ( SOUND_VERSION >= 0x030904 )
1648
1657
                frames = framesAvail;
1649
1658
 
1650
1659
                PA_ENSURE( PaOssStreamComponent_Write( stream->playback, &frames ) );
1651
 
                assert( frames == framesAvail );
1652
 
 
1653
 
                /* TODO: handle bytesWritten != bytesRequested (slippage?) */
 
1660
                if( frames < framesAvail )
 
1661
                {
 
1662
                    /* TODO: handle bytesWritten != bytesRequested (slippage?) */
 
1663
                    PA_DEBUG(( "Wrote %lu less frames than requested\n", framesAvail - frames ));
 
1664
                }
1654
1665
            }
1655
1666
 
1656
1667
            framesAvail -= framesProcessed;
1929
1940
 
1930
1941
    if( ioctl( stream->playback->fd, SNDCTL_DSP_GETODELAY, &delay ) < 0 )
1931
1942
        return paUnanticipatedHostError;
1932
 
    
 
1943
 
1933
1944
    return (PaOssStreamComponent_BufferSize( stream->playback ) - delay) / PaOssStreamComponent_FrameSize( stream->playback );
1934
1945
}
1935
1946
 
1936
 
const char *PaOSS_GetInputDevice( PaStream* s )
 
1947
const char *PaOSS_GetStreamInputDevice( PaStream* s )
1937
1948
{
1938
1949
    PaOssStream *stream = (PaOssStream*)s;
1939
1950
 
1945
1956
   return NULL;
1946
1957
}
1947
1958
 
1948
 
const char *PaOSS_GetOutputDevice( PaStream* s )
 
1959
const char *PaOSS_GetStreamOutputDevice( PaStream* s )
1949
1960
{
1950
1961
    PaOssStream *stream = (PaOssStream*)s;
1951
1962