src/audio/ums/SDL_umsaudio.c
author Sam Lantinga
Mon, 06 Feb 2006 08:28:51 +0000
changeset 1330 450721ad5436
parent 1312 c9b51268668f
child 1336 3692456e7b0f
permissions -rw-r--r--
It's now possible to build SDL without any C runtime at all on Windows,
using Visual C++ 2005
slouken@0
     1
/*
slouken@1312
     2
    SDL - Simple DirectMedia Layer
slouken@1312
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@0
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@0
    18
slouken@0
    19
    Carsten Griwodz
slouken@0
    20
    griff@kom.tu-darmstadt.de
slouken@0
    21
slouken@0
    22
    based on linux/SDL_dspaudio.c by Sam Lantinga
slouken@0
    23
*/
slouken@0
    24
slouken@0
    25
/* Allow access to a raw mixing buffer */
slouken@0
    26
slouken@0
    27
#include <stdlib.h>
slouken@0
    28
#include <stdio.h>
slouken@0
    29
#include <string.h>
slouken@0
    30
#include <errno.h>
slouken@0
    31
#include <unistd.h>
slouken@0
    32
#include <fcntl.h>
slouken@0
    33
#include <sys/types.h>
slouken@0
    34
#include <sys/time.h>
slouken@0
    35
#include <sys/ioctl.h>
slouken@0
    36
#include <sys/stat.h>
slouken@0
    37
#include <sys/mman.h>
slouken@0
    38
slouken@0
    39
#include "SDL_audio.h"
slouken@0
    40
#include "SDL_error.h"
slouken@0
    41
#include "SDL_audio_c.h"
slouken@0
    42
#include "SDL_audiodev_c.h"
slouken@0
    43
#include "SDL_umsaudio.h"
slouken@0
    44
slouken@0
    45
/* The tag name used by UMS audio */
slouken@0
    46
#define UMS_DRIVER_NAME         "ums"
slouken@0
    47
slouken@0
    48
#define DEBUG_AUDIO 1
slouken@0
    49
slouken@0
    50
/* Audio driver functions */
slouken@0
    51
static int UMS_OpenAudio(_THIS, SDL_AudioSpec *spec);
slouken@0
    52
static void UMS_PlayAudio(_THIS);
slouken@0
    53
static Uint8 *UMS_GetAudioBuf(_THIS);
slouken@0
    54
static void UMS_CloseAudio(_THIS);
slouken@0
    55
slouken@0
    56
static UMSAudioDevice_ReturnCode UADOpen(_THIS,  string device, string mode, long flags);
slouken@0
    57
static UMSAudioDevice_ReturnCode UADClose(_THIS);
slouken@0
    58
static UMSAudioDevice_ReturnCode UADGetBitsPerSample(_THIS, long* bits);
slouken@0
    59
static UMSAudioDevice_ReturnCode UADSetBitsPerSample(_THIS, long bits);
slouken@0
    60
static UMSAudioDevice_ReturnCode UADSetSampleRate(_THIS, long rate, long* set_rate);
slouken@0
    61
static UMSAudioDevice_ReturnCode UADSetByteOrder(_THIS, string byte_order);
slouken@0
    62
static UMSAudioDevice_ReturnCode UADSetAudioFormatType(_THIS, string fmt);
slouken@0
    63
static UMSAudioDevice_ReturnCode UADSetNumberFormat(_THIS, string fmt);
slouken@0
    64
static UMSAudioDevice_ReturnCode UADInitialize(_THIS);
slouken@0
    65
static UMSAudioDevice_ReturnCode UADStart(_THIS);
slouken@0
    66
static UMSAudioDevice_ReturnCode UADStop(_THIS);
slouken@0
    67
static UMSAudioDevice_ReturnCode UADSetTimeFormat(_THIS,  UMSAudioTypes_TimeFormat fmt );
slouken@0
    68
static UMSAudioDevice_ReturnCode UADWriteBuffSize(_THIS,  long* buff_size );
slouken@0
    69
static UMSAudioDevice_ReturnCode UADWriteBuffRemain(_THIS,  long* buff_size );
slouken@0
    70
static UMSAudioDevice_ReturnCode UADWriteBuffUsed(_THIS,  long* buff_size );
slouken@0
    71
static UMSAudioDevice_ReturnCode UADSetDMABufferSize(_THIS,  long bytes, long* bytes_ret );
slouken@0
    72
static UMSAudioDevice_ReturnCode UADSetVolume(_THIS,  long volume );
slouken@0
    73
static UMSAudioDevice_ReturnCode UADSetBalance(_THIS,  long balance );
slouken@0
    74
static UMSAudioDevice_ReturnCode UADSetChannels(_THIS,  long channels );
slouken@0
    75
static UMSAudioDevice_ReturnCode UADPlayRemainingData(_THIS,  boolean block );
slouken@0
    76
static UMSAudioDevice_ReturnCode UADEnableOutput(_THIS,  string output, long* left_gain, long* right_gain);
slouken@0
    77
static UMSAudioDevice_ReturnCode UADWrite(_THIS,  UMSAudioTypes_Buffer* buff, long samples, long* samples_written);
slouken@0
    78
slouken@0
    79
/* Audio driver bootstrap functions */
slouken@0
    80
static int Audio_Available(void)
slouken@0
    81
{
slouken@0
    82
    return 1;
slouken@0
    83
}
slouken@0
    84
slouken@0
    85
static void Audio_DeleteDevice(_THIS)
slouken@0
    86
{
slouken@0
    87
    if(this->hidden->playbuf._buffer) free(this->hidden->playbuf._buffer);
slouken@0
    88
    if(this->hidden->fillbuf._buffer) free(this->hidden->fillbuf._buffer);
slouken@0
    89
    _somFree( this->hidden->umsdev );
slouken@0
    90
    free(this->hidden);
slouken@0
    91
    free(this);
slouken@0
    92
}
slouken@0
    93
slouken@0
    94
static SDL_AudioDevice *Audio_CreateDevice(int devindex)
slouken@0
    95
{
slouken@0
    96
    SDL_AudioDevice *this;
slouken@0
    97
slouken@0
    98
    /*
slouken@0
    99
     * Allocate and initialize management storage and private management
slouken@0
   100
     * storage for this SDL-using library.
slouken@0
   101
     */
slouken@0
   102
    this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
slouken@0
   103
    if ( this ) {
slouken@0
   104
        memset(this, 0, (sizeof *this));
slouken@0
   105
        this->hidden = (struct SDL_PrivateAudioData *)malloc((sizeof *this->hidden));
slouken@0
   106
    }
slouken@0
   107
    if ( (this == NULL) || (this->hidden == NULL) ) {
slouken@0
   108
        SDL_OutOfMemory();
slouken@0
   109
        if ( this ) {
slouken@0
   110
            free(this);
slouken@0
   111
        }
slouken@0
   112
        return(0);
slouken@0
   113
    }
slouken@0
   114
    memset(this->hidden, 0, (sizeof *this->hidden));
slouken@0
   115
#ifdef DEBUG_AUDIO
slouken@0
   116
    fprintf(stderr, "Creating UMS Audio device\n");
slouken@0
   117
#endif
slouken@0
   118
slouken@0
   119
    /*
slouken@0
   120
     * Calls for UMS env initialization and audio object construction.
slouken@0
   121
     */
slouken@0
   122
    this->hidden->ev     = somGetGlobalEnvironment();
slouken@0
   123
    this->hidden->umsdev = UMSAudioDeviceNew();
slouken@0
   124
slouken@0
   125
    /*
slouken@0
   126
     * Set the function pointers.
slouken@0
   127
     */
slouken@0
   128
    this->OpenAudio   = UMS_OpenAudio;
slouken@0
   129
    this->WaitAudio   = NULL;           /* we do blocking output */
slouken@0
   130
    this->PlayAudio   = UMS_PlayAudio;
slouken@0
   131
    this->GetAudioBuf = UMS_GetAudioBuf;
slouken@0
   132
    this->CloseAudio  = UMS_CloseAudio;
slouken@0
   133
    this->free        = Audio_DeleteDevice;
slouken@0
   134
slouken@0
   135
#ifdef DEBUG_AUDIO
slouken@0
   136
    fprintf(stderr, "done\n");
slouken@0
   137
#endif
slouken@0
   138
    return this;
slouken@0
   139
}
slouken@0
   140
slouken@0
   141
AudioBootStrap UMS_bootstrap = {
slouken@0
   142
	UMS_DRIVER_NAME, "AUX UMS audio",
slouken@0
   143
	Audio_Available, Audio_CreateDevice
slouken@0
   144
};
slouken@0
   145
slouken@0
   146
static Uint8 *UMS_GetAudioBuf(_THIS)
slouken@0
   147
{
slouken@0
   148
#ifdef DEBUG_AUDIO
slouken@0
   149
    fprintf(stderr, "enter UMS_GetAudioBuf\n");
slouken@0
   150
#endif
slouken@0
   151
    return this->hidden->fillbuf._buffer;
slouken@0
   152
/*
slouken@0
   153
    long                      bufSize;
slouken@0
   154
    UMSAudioDevice_ReturnCode rc;
slouken@0
   155
slouken@0
   156
    rc = UADSetTimeFormat(this, UMSAudioTypes_Bytes );
slouken@0
   157
    rc = UADWriteBuffSize(this,  bufSize );
slouken@0
   158
*/
slouken@0
   159
}
slouken@0
   160
slouken@0
   161
static void UMS_CloseAudio(_THIS)
slouken@0
   162
{
slouken@0
   163
    UMSAudioDevice_ReturnCode rc;
slouken@0
   164
slouken@0
   165
#ifdef DEBUG_AUDIO
slouken@0
   166
    fprintf(stderr, "enter UMS_CloseAudio\n");
slouken@0
   167
#endif
slouken@0
   168
    rc = UADPlayRemainingData(this, TRUE);
slouken@0
   169
    rc = UADStop(this);
slouken@0
   170
    rc = UADClose(this);
slouken@0
   171
}
slouken@0
   172
slouken@0
   173
static void UMS_PlayAudio(_THIS)
slouken@0
   174
{
slouken@0
   175
    UMSAudioDevice_ReturnCode rc;
slouken@0
   176
    long                      samplesToWrite;
slouken@0
   177
    long                      samplesWritten;
slouken@0
   178
    UMSAudioTypes_Buffer      swpbuf;
slouken@0
   179
slouken@0
   180
#ifdef DEBUG_AUDIO
slouken@0
   181
    fprintf(stderr, "enter UMS_PlayAudio\n");
slouken@0
   182
#endif
slouken@0
   183
    samplesToWrite = this->hidden->playbuf._length/this->hidden->bytesPerSample;
slouken@0
   184
    do
slouken@0
   185
    {
slouken@0
   186
        rc = UADWrite(this,  &this->hidden->playbuf,
slouken@0
   187
		       samplesToWrite,
slouken@0
   188
	               &samplesWritten );
slouken@0
   189
	samplesToWrite -= samplesWritten;
slouken@0
   190
slouken@0
   191
	/* rc values: UMSAudioDevice_Success
slouken@0
   192
	 *            UMSAudioDevice_Failure
slouken@0
   193
	 *            UMSAudioDevice_Preempted
slouken@0
   194
	 *            UMSAudioDevice_Interrupted
slouken@0
   195
	 *            UMSAudioDevice_DeviceError
slouken@0
   196
	 */
slouken@0
   197
	if ( rc == UMSAudioDevice_DeviceError ) {
slouken@0
   198
#ifdef DEBUG_AUDIO
slouken@0
   199
	    fprintf(stderr, "Returning from PlayAudio with devices error\n");
slouken@0
   200
#endif
slouken@0
   201
	    return;
slouken@0
   202
	}
slouken@0
   203
    }
slouken@0
   204
    while(samplesToWrite>0);
slouken@0
   205
slouken@0
   206
    SDL_LockAudio();
slouken@0
   207
    memcpy( &swpbuf,                &this->hidden->playbuf, sizeof(UMSAudioTypes_Buffer) );
slouken@0
   208
    memcpy( &this->hidden->playbuf, &this->hidden->fillbuf, sizeof(UMSAudioTypes_Buffer) );
slouken@0
   209
    memcpy( &this->hidden->fillbuf, &swpbuf,                sizeof(UMSAudioTypes_Buffer) );
slouken@0
   210
    SDL_UnlockAudio();
slouken@0
   211
slouken@0
   212
#ifdef DEBUG_AUDIO
slouken@0
   213
    fprintf(stderr, "Wrote audio data and swapped buffer\n");
slouken@0
   214
#endif
slouken@0
   215
}
slouken@0
   216
slouken@0
   217
#if 0
slouken@0
   218
// 	/* Set the DSP frequency */
slouken@0
   219
// 	value = spec->freq;
slouken@0
   220
// 	if ( ioctl(this->hidden->audio_fd, SOUND_PCM_WRITE_RATE, &value) < 0 ) {
slouken@0
   221
// 		SDL_SetError("Couldn't set audio frequency");
slouken@0
   222
// 		return(-1);
slouken@0
   223
// 	}
slouken@0
   224
// 	spec->freq = value;
slouken@0
   225
#endif
slouken@0
   226
slouken@0
   227
static int UMS_OpenAudio(_THIS, SDL_AudioSpec *spec)
slouken@0
   228
{
slouken@0
   229
    char*  audiodev = "/dev/paud0";
slouken@0
   230
    long   lgain;
slouken@0
   231
    long   rgain;
slouken@0
   232
    long   outRate;
slouken@0
   233
    long   outBufSize;
slouken@0
   234
    long   bitsPerSample;
slouken@0
   235
    long   samplesPerSec;
slouken@0
   236
    long   success;
slouken@0
   237
    Uint16 test_format;
slouken@0
   238
    int    frag_spec;
slouken@0
   239
    UMSAudioDevice_ReturnCode rc;
slouken@0
   240
slouken@0
   241
#ifdef DEBUG_AUDIO
slouken@0
   242
    fprintf(stderr, "enter UMS_OpenAudio\n");
slouken@0
   243
#endif
slouken@0
   244
    rc = UADOpen(this, audiodev,"PLAY", UMSAudioDevice_BlockingIO);
slouken@0
   245
    if ( rc != UMSAudioDevice_Success ) {
slouken@0
   246
	SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno));
slouken@0
   247
	return -1;
slouken@0
   248
    }
slouken@0
   249
 
slouken@0
   250
    rc = UADSetAudioFormatType(this, "PCM"); 
slouken@0
   251
slouken@0
   252
    success = 0;
slouken@0
   253
    test_format = SDL_FirstAudioFormat(spec->format);
slouken@0
   254
    do
slouken@0
   255
    {
slouken@0
   256
#ifdef DEBUG_AUDIO
slouken@0
   257
        fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
slouken@0
   258
#endif
slouken@0
   259
        switch ( test_format )
slouken@0
   260
        {
slouken@0
   261
        case AUDIO_U8:
slouken@0
   262
/* from the mac code: better ? */
slouken@0
   263
/* sample_bits = spec->size / spec->samples / spec->channels * 8; */
slouken@0
   264
	    success       = 1;
slouken@0
   265
            bitsPerSample = 8;
slouken@0
   266
            rc = UADSetSampleRate(this,  spec->freq << 16, &outRate );
slouken@0
   267
            rc = UADSetByteOrder(this, "MSB");       /* irrelevant */
slouken@0
   268
            rc = UADSetNumberFormat(this, "UNSIGNED");
slouken@0
   269
            break;
slouken@0
   270
        case AUDIO_S8:
slouken@0
   271
	    success       = 1;
slouken@0
   272
            bitsPerSample = 8;
slouken@0
   273
            rc = UADSetSampleRate(this,  spec->freq << 16, &outRate );
slouken@0
   274
            rc = UADSetByteOrder(this, "MSB");       /* irrelevant */
slouken@0
   275
            rc = UADSetNumberFormat(this, "SIGNED");
slouken@0
   276
            break;
slouken@0
   277
        case AUDIO_S16LSB:
slouken@0
   278
	    success       = 1;
slouken@0
   279
            bitsPerSample = 16;
slouken@0
   280
            rc = UADSetSampleRate(this,  spec->freq << 16, &outRate );
slouken@0
   281
            rc = UADSetByteOrder(this, "LSB");
slouken@0
   282
            rc = UADSetNumberFormat(this, "SIGNED");
slouken@0
   283
            break;
slouken@0
   284
        case AUDIO_S16MSB:
slouken@0
   285
	    success       = 1;
slouken@0
   286
            bitsPerSample = 16;
slouken@0
   287
            rc = UADSetSampleRate(this,  spec->freq << 16, &outRate );
slouken@0
   288
            rc = UADSetByteOrder(this, "MSB");
slouken@0
   289
            rc = UADSetNumberFormat(this, "SIGNED");
slouken@0
   290
            break;
slouken@0
   291
        case AUDIO_U16LSB:
slouken@0
   292
	    success       = 1;
slouken@0
   293
            bitsPerSample = 16;
slouken@0
   294
            rc = UADSetSampleRate(this,  spec->freq << 16, &outRate );
slouken@0
   295
            rc = UADSetByteOrder(this, "LSB");
slouken@0
   296
            rc = UADSetNumberFormat(this, "UNSIGNED");
slouken@0
   297
            break;
slouken@0
   298
        case AUDIO_U16MSB:
slouken@0
   299
	    success       = 1;
slouken@0
   300
            bitsPerSample = 16;
slouken@0
   301
            rc = UADSetSampleRate(this,  spec->freq << 16, &outRate );
slouken@0
   302
            rc = UADSetByteOrder(this, "MSB");
slouken@0
   303
            rc = UADSetNumberFormat(this, "UNSIGNED");
slouken@0
   304
            break;
slouken@0
   305
        default:
slouken@0
   306
            break;
slouken@0
   307
        }
slouken@0
   308
        if ( ! success ) {
slouken@0
   309
            test_format = SDL_NextAudioFormat();
slouken@0
   310
        }
slouken@0
   311
    }
slouken@0
   312
    while ( ! success && test_format );
slouken@0
   313
slouken@0
   314
    if ( success == 0 ) {
slouken@0
   315
        SDL_SetError("Couldn't find any hardware audio formats");
slouken@0
   316
        return -1;
slouken@0
   317
    }
slouken@0
   318
slouken@0
   319
    spec->format = test_format;
slouken@0
   320
slouken@0
   321
    for ( frag_spec = 0; (0x01<<frag_spec) < spec->size; ++frag_spec );
slouken@0
   322
    if ( (0x01<<frag_spec) != spec->size ) {
slouken@0
   323
        SDL_SetError("Fragment size must be a power of two");
slouken@0
   324
        return -1;
slouken@0
   325
    }
slouken@0
   326
    if ( frag_spec > 2048 ) frag_spec = 2048;
slouken@0
   327
slouken@0
   328
    this->hidden->bytesPerSample   = (bitsPerSample / 8) * spec->channels;
slouken@0
   329
    samplesPerSec                  = this->hidden->bytesPerSample * outRate;
slouken@0
   330
slouken@0
   331
    this->hidden->playbuf._length  = 0;
slouken@0
   332
    this->hidden->playbuf._maximum = spec->size;
slouken@0
   333
    this->hidden->playbuf._buffer  = (unsigned char*)malloc(spec->size);
slouken@0
   334
    this->hidden->fillbuf._length  = 0;
slouken@0
   335
    this->hidden->fillbuf._maximum = spec->size;
slouken@0
   336
    this->hidden->fillbuf._buffer  = (unsigned char*)malloc(spec->size);
slouken@0
   337
slouken@0
   338
    rc = UADSetBitsPerSample(this,  bitsPerSample );
slouken@0
   339
    rc = UADSetDMABufferSize(this,  frag_spec, &outBufSize );
slouken@0
   340
    rc = UADSetChannels(this, spec->channels);      /* functions reduces to mono or stereo */
slouken@0
   341
slouken@0
   342
    lgain = 100; /*maximum left input gain*/
slouken@0
   343
    rgain = 100; /*maimum right input gain*/
slouken@0
   344
    rc = UADEnableOutput(this, "LINE_OUT",&lgain,&rgain);
slouken@0
   345
    rc = UADInitialize(this);
slouken@0
   346
    rc = UADStart(this);
slouken@0
   347
    rc = UADSetVolume(this, 100);
slouken@0
   348
    rc = UADSetBalance(this, 0);
slouken@0
   349
slouken@0
   350
    /* We're ready to rock and roll. :-) */
slouken@0
   351
    return 0;
slouken@0
   352
}
slouken@0
   353
slouken@0
   354

slouken@0
   355
static UMSAudioDevice_ReturnCode UADGetBitsPerSample(_THIS, long* bits)
slouken@0
   356
{
slouken@0
   357
    return UMSAudioDevice_get_bits_per_sample( this->hidden->umsdev,
slouken@0
   358
					       this->hidden->ev,
slouken@0
   359
					       bits );
slouken@0
   360
}
slouken@0
   361
slouken@0
   362
static UMSAudioDevice_ReturnCode UADSetBitsPerSample(_THIS, long bits)
slouken@0
   363
{
slouken@0
   364
    return UMSAudioDevice_set_bits_per_sample( this->hidden->umsdev,
slouken@0
   365
					       this->hidden->ev,
slouken@0
   366
					       bits );
slouken@0
   367
}
slouken@0
   368
slouken@0
   369
static UMSAudioDevice_ReturnCode UADSetSampleRate(_THIS, long rate, long* set_rate)
slouken@0
   370
{
slouken@0
   371
    /* from the mac code: sample rate = spec->freq << 16; */
slouken@0
   372
    return UMSAudioDevice_set_sample_rate( this->hidden->umsdev,
slouken@0
   373
					   this->hidden->ev,
slouken@0
   374
					   rate,
slouken@0
   375
					   set_rate );
slouken@0
   376
}
slouken@0
   377
slouken@0
   378
static UMSAudioDevice_ReturnCode UADSetByteOrder(_THIS, string byte_order)
slouken@0
   379
{
slouken@0
   380
    return UMSAudioDevice_set_byte_order( this->hidden->umsdev,
slouken@0
   381
					  this->hidden->ev,
slouken@0
   382
					  byte_order );
slouken@0
   383
}
slouken@0
   384
slouken@0
   385
static UMSAudioDevice_ReturnCode UADSetAudioFormatType(_THIS, string fmt)
slouken@0
   386
{
slouken@0
   387
    /* possible PCM, A_LAW or MU_LAW */
slouken@0
   388
    return UMSAudioDevice_set_audio_format_type( this->hidden->umsdev,
slouken@0
   389
						 this->hidden->ev,
slouken@0
   390
						 fmt );
slouken@0
   391
}
slouken@0
   392
slouken@0
   393
static UMSAudioDevice_ReturnCode UADSetNumberFormat(_THIS, string fmt)
slouken@0
   394
{
slouken@0
   395
    /* possible SIGNED, UNSIGNED, or TWOS_COMPLEMENT */
slouken@0
   396
    return UMSAudioDevice_set_number_format( this->hidden->umsdev,
slouken@0
   397
					     this->hidden->ev,
slouken@0
   398
					     fmt );
slouken@0
   399
}
slouken@0
   400
slouken@0
   401
static UMSAudioDevice_ReturnCode UADInitialize(_THIS)
slouken@0
   402
{
slouken@0
   403
    return UMSAudioDevice_initialize( this->hidden->umsdev,
slouken@0
   404
				      this->hidden->ev );
slouken@0
   405
}
slouken@0
   406
slouken@0
   407
static UMSAudioDevice_ReturnCode UADStart(_THIS)
slouken@0
   408
{
slouken@0
   409
    return UMSAudioDevice_start( this->hidden->umsdev,
slouken@0
   410
				 this->hidden->ev );
slouken@0
   411
}
slouken@0
   412
slouken@0
   413
static UMSAudioDevice_ReturnCode UADSetTimeFormat(_THIS,  UMSAudioTypes_TimeFormat fmt )
slouken@0
   414
{
slouken@0
   415
    /*
slouken@0
   416
     * Switches the time format to the new format, immediately.
slouken@0
   417
     * possible UMSAudioTypes_Msecs, UMSAudioTypes_Bytes or UMSAudioTypes_Samples
slouken@0
   418
     */
slouken@0
   419
    return UMSAudioDevice_set_time_format( this->hidden->umsdev,
slouken@0
   420
					   this->hidden->ev,
slouken@0
   421
					   fmt );
slouken@0
   422
}
slouken@0
   423
slouken@0
   424
static UMSAudioDevice_ReturnCode UADWriteBuffSize(_THIS,  long* buff_size )
slouken@0
   425
{
slouken@0
   426
    /*
slouken@0
   427
     * returns write buffer size in the current time format
slouken@0
   428
     */
slouken@0
   429
    return UMSAudioDevice_write_buff_size( this->hidden->umsdev,
slouken@0
   430
                                           this->hidden->ev,
slouken@0
   431
					   buff_size );
slouken@0
   432
}
slouken@0
   433
slouken@0
   434
static UMSAudioDevice_ReturnCode UADWriteBuffRemain(_THIS,  long* buff_size )
slouken@0
   435
{
slouken@0
   436
    /*
slouken@0
   437
     * returns amount of available space in the write buffer
slouken@0
   438
     * in the current time format
slouken@0
   439
     */
slouken@0
   440
    return UMSAudioDevice_write_buff_remain( this->hidden->umsdev,
slouken@0
   441
                                             this->hidden->ev,
slouken@0
   442
					     buff_size );
slouken@0
   443
}
slouken@0
   444
slouken@0
   445
static UMSAudioDevice_ReturnCode UADWriteBuffUsed(_THIS,  long* buff_size )
slouken@0
   446
{
slouken@0
   447
    /*
slouken@0
   448
     * returns amount of filled space in the write buffer
slouken@0
   449
     * in the current time format
slouken@0
   450
     */
slouken@0
   451
    return UMSAudioDevice_write_buff_used( this->hidden->umsdev,
slouken@0
   452
                                           this->hidden->ev,
slouken@0
   453
					   buff_size );
slouken@0
   454
}
slouken@0
   455
slouken@0
   456
static UMSAudioDevice_ReturnCode UADSetDMABufferSize(_THIS,  long bytes, long* bytes_ret )
slouken@0
   457
{
slouken@0
   458
    /*
slouken@0
   459
     * Request a new DMA buffer size, maximum requested size 2048.
slouken@0
   460
     * Takes effect with next initialize() call.
slouken@0
   461
     * Devices may or may not support DMA.
slouken@0
   462
     */
slouken@0
   463
    return UMSAudioDevice_set_DMA_buffer_size( this->hidden->umsdev,
slouken@0
   464
					       this->hidden->ev,
slouken@0
   465
					       bytes,
slouken@0
   466
					       bytes_ret );
slouken@0
   467
}
slouken@0
   468
slouken@0
   469
static UMSAudioDevice_ReturnCode UADSetVolume(_THIS,  long volume )
slouken@0
   470
{
slouken@0
   471
    /*
slouken@0
   472
     * Set the volume.
slouken@0
   473
     * Takes effect immediately.
slouken@0
   474
     */
slouken@0
   475
    return UMSAudioDevice_set_volume( this->hidden->umsdev,
slouken@0
   476
				      this->hidden->ev,
slouken@0
   477
				      volume );
slouken@0
   478
}
slouken@0
   479
slouken@0
   480
static UMSAudioDevice_ReturnCode UADSetBalance(_THIS,  long balance )
slouken@0
   481
{
slouken@0
   482
    /*
slouken@0
   483
     * Set the balance.
slouken@0
   484
     * Takes effect immediately.
slouken@0
   485
     */
slouken@0
   486
    return UMSAudioDevice_set_balance( this->hidden->umsdev,
slouken@0
   487
				       this->hidden->ev,
slouken@0
   488
				       balance );
slouken@0
   489
}
slouken@0
   490
slouken@0
   491
static UMSAudioDevice_ReturnCode UADSetChannels(_THIS,  long channels )
slouken@0
   492
{
slouken@0
   493
    /*
slouken@0
   494
     * Set mono or stereo.
slouken@0
   495
     * Takes effect with next initialize() call.
slouken@0
   496
     */
slouken@0
   497
    if ( channels != 1 ) channels = 2;
slouken@0
   498
    return UMSAudioDevice_set_number_of_channels( this->hidden->umsdev,
slouken@0
   499
				                  this->hidden->ev,
slouken@0
   500
				                  channels );
slouken@0
   501
}
slouken@0
   502
slouken@0
   503
static UMSAudioDevice_ReturnCode UADOpen(_THIS,  string device, string mode, long flags)
slouken@0
   504
{
slouken@0
   505
    return UMSAudioDevice_open( this->hidden->umsdev,
slouken@0
   506
				this->hidden->ev,
slouken@0
   507
				device,
slouken@0
   508
				mode,
slouken@0
   509
				flags );
slouken@0
   510
}
slouken@0
   511
slouken@0
   512
static UMSAudioDevice_ReturnCode UADWrite(_THIS,  UMSAudioTypes_Buffer* buff,
slouken@0
   513
                                           long samples,
slouken@0
   514
					   long* samples_written)
slouken@0
   515
{
slouken@0
   516
    return UMSAudioDevice_write( this->hidden->umsdev,
slouken@0
   517
				 this->hidden->ev,
slouken@0
   518
				 buff,
slouken@0
   519
				 samples,
slouken@0
   520
				 samples_written );
slouken@0
   521
}
slouken@0
   522
slouken@0
   523
static UMSAudioDevice_ReturnCode UADPlayRemainingData(_THIS,  boolean block )
slouken@0
   524
{
slouken@0
   525
    return UMSAudioDevice_play_remaining_data( this->hidden->umsdev,
slouken@0
   526
					       this->hidden->ev,
slouken@0
   527
					       block);
slouken@0
   528
}
slouken@0
   529
slouken@0
   530
static UMSAudioDevice_ReturnCode UADStop(_THIS)
slouken@0
   531
{
slouken@0
   532
    return UMSAudioDevice_stop( this->hidden->umsdev,
slouken@0
   533
				this->hidden->ev );
slouken@0
   534
}
slouken@0
   535
slouken@0
   536
static UMSAudioDevice_ReturnCode UADClose(_THIS)
slouken@0
   537
{
slouken@0
   538
    return UMSAudioDevice_close( this->hidden->umsdev,
slouken@0
   539
				 this->hidden->ev );
slouken@0
   540
}
slouken@0
   541
slouken@0
   542
static UMSAudioDevice_ReturnCode UADEnableOutput(_THIS,  string output, long* left_gain, long* right_gain)
slouken@0
   543
{
slouken@0
   544
    return UMSAudioDevice_enable_output( this->hidden->umsdev,
slouken@0
   545
					 this->hidden->ev,
slouken@0
   546
					 output,
slouken@0
   547
					 left_gain,
slouken@0
   548
					 right_gain );
slouken@0
   549
}
slouken@0
   550