19682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/*
29682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    SDL - Simple DirectMedia Layer
39682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    Copyright (C) 1997-2012 Sam Lantinga
49682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
59682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    This library is free software; you can redistribute it and/or
69682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    modify it under the terms of the GNU Lesser General Public
79682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    License as published by the Free Software Foundation; either
89682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    version 2.1 of the License, or (at your option) any later version.
99682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    This library is distributed in the hope that it will be useful,
119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    but WITHOUT ANY WARRANTY; without even the implied warranty of
129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    Lesser General Public License for more details.
149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    You should have received a copy of the GNU Lesser General Public
169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    License along with this library; if not, write to the Free Software
179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    Carsten Griwodz
209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    griff@kom.tu-darmstadt.de
219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    based on linux/SDL_dspaudio.c by Sam Lantinga
239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/
249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_config.h"
259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Allow access to a raw mixing buffer */
279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <errno.h>
299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <unistd.h>
309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <fcntl.h>
319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <sys/types.h>
329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <sys/time.h>
339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <sys/ioctl.h>
349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <sys/stat.h>
359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <sys/mman.h>
369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_audio.h"
389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "../SDL_audio_c.h"
399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "../SDL_audiodev_c.h"
409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL_umsaudio.h"
419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* The tag name used by UMS audio */
439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define UMS_DRIVER_NAME         "ums"
449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define DEBUG_AUDIO 1
469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Audio driver functions */
489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int UMS_OpenAudio(_THIS, SDL_AudioSpec *spec);
499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void UMS_PlayAudio(_THIS);
509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic Uint8 *UMS_GetAudioBuf(_THIS);
519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void UMS_CloseAudio(_THIS);
529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADOpen(_THIS,  string device, string mode, long flags);
549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADClose(_THIS);
559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADGetBitsPerSample(_THIS, long* bits);
569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetBitsPerSample(_THIS, long bits);
579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetSampleRate(_THIS, long rate, long* set_rate);
589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetByteOrder(_THIS, string byte_order);
599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetAudioFormatType(_THIS, string fmt);
609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetNumberFormat(_THIS, string fmt);
619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADInitialize(_THIS);
629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADStart(_THIS);
639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADStop(_THIS);
649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetTimeFormat(_THIS,  UMSAudioTypes_TimeFormat fmt );
659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADWriteBuffSize(_THIS,  long* buff_size );
669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADWriteBuffRemain(_THIS,  long* buff_size );
679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADWriteBuffUsed(_THIS,  long* buff_size );
689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetDMABufferSize(_THIS,  long bytes, long* bytes_ret );
699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetVolume(_THIS,  long volume );
709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetBalance(_THIS,  long balance );
719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetChannels(_THIS,  long channels );
729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADPlayRemainingData(_THIS,  boolean block );
739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADEnableOutput(_THIS,  string output, long* left_gain, long* right_gain);
749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADWrite(_THIS,  UMSAudioTypes_Buffer* buff, long samples, long* samples_written);
759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Audio driver bootstrap functions */
779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int Audio_Available(void)
789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return 1;
809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void Audio_DeleteDevice(_THIS)
839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    if(this->hidden->playbuf._buffer) SDL_free(this->hidden->playbuf._buffer);
859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    if(this->hidden->fillbuf._buffer) SDL_free(this->hidden->fillbuf._buffer);
869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    _somFree( this->hidden->umsdev );
879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    SDL_free(this->hidden);
889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    SDL_free(this);
899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic SDL_AudioDevice *Audio_CreateDevice(int devindex)
929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    SDL_AudioDevice *this;
949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /*
969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * Allocate and initialize management storage and private management
979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * storage for this SDL-using library.
989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     */
999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice));
1009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    if ( this ) {
1019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        SDL_memset(this, 0, (sizeof *this));
1029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc((sizeof *this->hidden));
1039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    }
1049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    if ( (this == NULL) || (this->hidden == NULL) ) {
1059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        SDL_OutOfMemory();
1069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        if ( this ) {
1079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            SDL_free(this);
1089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        }
1099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        return(0);
1109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    }
1119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
1129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef DEBUG_AUDIO
1139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    fprintf(stderr, "Creating UMS Audio device\n");
1149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif
1159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /*
1179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * Calls for UMS env initialization and audio object construction.
1189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     */
1199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    this->hidden->ev     = somGetGlobalEnvironment();
1209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    this->hidden->umsdev = UMSAudioDeviceNew();
1219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /*
1239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * Set the function pointers.
1249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     */
1259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    this->OpenAudio   = UMS_OpenAudio;
1269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    this->WaitAudio   = NULL;           /* we do blocking output */
1279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    this->PlayAudio   = UMS_PlayAudio;
1289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    this->GetAudioBuf = UMS_GetAudioBuf;
1299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    this->CloseAudio  = UMS_CloseAudio;
1309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    this->free        = Audio_DeleteDevice;
1319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef DEBUG_AUDIO
1339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    fprintf(stderr, "done\n");
1349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif
1359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return this;
1369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
1379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallAudioBootStrap UMS_bootstrap = {
1399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	UMS_DRIVER_NAME, "AIX UMS audio",
1409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	Audio_Available, Audio_CreateDevice
1419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall};
1429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic Uint8 *UMS_GetAudioBuf(_THIS)
1449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
1459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef DEBUG_AUDIO
1469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    fprintf(stderr, "enter UMS_GetAudioBuf\n");
1479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif
1489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return this->hidden->fillbuf._buffer;
1499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/*
1509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    long                      bufSize;
1519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    UMSAudioDevice_ReturnCode rc;
1529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    rc = UADSetTimeFormat(this, UMSAudioTypes_Bytes );
1549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    rc = UADWriteBuffSize(this,  bufSize );
1559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall*/
1569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
1579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void UMS_CloseAudio(_THIS)
1599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
1609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    UMSAudioDevice_ReturnCode rc;
1619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef DEBUG_AUDIO
1639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    fprintf(stderr, "enter UMS_CloseAudio\n");
1649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif
1659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    rc = UADPlayRemainingData(this, TRUE);
1669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    rc = UADStop(this);
1679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    rc = UADClose(this);
1689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
1699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void UMS_PlayAudio(_THIS)
1719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
1729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    UMSAudioDevice_ReturnCode rc;
1739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    long                      samplesToWrite;
1749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    long                      samplesWritten;
1759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    UMSAudioTypes_Buffer      swpbuf;
1769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef DEBUG_AUDIO
1789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    fprintf(stderr, "enter UMS_PlayAudio\n");
1799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif
1809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    samplesToWrite = this->hidden->playbuf._length/this->hidden->bytesPerSample;
1819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    do
1829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    {
1839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        rc = UADWrite(this,  &this->hidden->playbuf,
1849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		       samplesToWrite,
1859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	               &samplesWritten );
1869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	samplesToWrite -= samplesWritten;
1879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* rc values: UMSAudioDevice_Success
1899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	 *            UMSAudioDevice_Failure
1909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	 *            UMSAudioDevice_Preempted
1919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	 *            UMSAudioDevice_Interrupted
1929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	 *            UMSAudioDevice_DeviceError
1939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	 */
1949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	if ( rc == UMSAudioDevice_DeviceError ) {
1959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef DEBUG_AUDIO
1969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	    fprintf(stderr, "Returning from PlayAudio with devices error\n");
1979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif
1989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	    return;
1999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	}
2009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    }
2019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    while(samplesToWrite>0);
2029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    SDL_LockAudio();
2049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    SDL_memcpy( &swpbuf,                &this->hidden->playbuf, sizeof(UMSAudioTypes_Buffer) );
2059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    SDL_memcpy( &this->hidden->playbuf, &this->hidden->fillbuf, sizeof(UMSAudioTypes_Buffer) );
2069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    SDL_memcpy( &this->hidden->fillbuf, &swpbuf,                sizeof(UMSAudioTypes_Buffer) );
2079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    SDL_UnlockAudio();
2089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef DEBUG_AUDIO
2109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    fprintf(stderr, "Wrote audio data and swapped buffer\n");
2119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif
2129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
2139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#if 0
2159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall// 	/* Set the DSP frequency */
2169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall// 	value = spec->freq;
2179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall// 	if ( ioctl(this->hidden->audio_fd, SOUND_PCM_WRITE_RATE, &value) < 0 ) {
2189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall// 		SDL_SetError("Couldn't set audio frequency");
2199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall// 		return(-1);
2209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall// 	}
2219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall// 	spec->freq = value;
2229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif
2239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic int UMS_OpenAudio(_THIS, SDL_AudioSpec *spec)
2259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
2269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    char*  audiodev = "/dev/paud0";
2279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    long   lgain;
2289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    long   rgain;
2299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    long   outRate;
2309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    long   outBufSize;
2319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    long   bitsPerSample;
2329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    long   samplesPerSec;
2339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    long   success;
2349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    Uint16 test_format;
2359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    int    frag_spec;
2369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    UMSAudioDevice_ReturnCode rc;
2379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef DEBUG_AUDIO
2399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    fprintf(stderr, "enter UMS_OpenAudio\n");
2409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif
2419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    rc = UADOpen(this, audiodev,"PLAY", UMSAudioDevice_BlockingIO);
2429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    if ( rc != UMSAudioDevice_Success ) {
2439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno));
2449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	return -1;
2459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    }
2469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    rc = UADSetAudioFormatType(this, "PCM");
2489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
2499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    success = 0;
2509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    test_format = SDL_FirstAudioFormat(spec->format);
2519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    do
2529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    {
2539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef DEBUG_AUDIO
2549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
2559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif
2569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        switch ( test_format )
2579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        {
2589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        case AUDIO_U8:
2599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* from the mac code: better ? */
2609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* sample_bits = spec->size / spec->samples / spec->channels * 8; */
2619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	    success       = 1;
2629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            bitsPerSample = 8;
2639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            rc = UADSetSampleRate(this,  spec->freq << 16, &outRate );
2649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            rc = UADSetByteOrder(this, "MSB");       /* irrelevant */
2659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            rc = UADSetNumberFormat(this, "UNSIGNED");
2669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            break;
2679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        case AUDIO_S8:
2689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	    success       = 1;
2699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            bitsPerSample = 8;
2709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            rc = UADSetSampleRate(this,  spec->freq << 16, &outRate );
2719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            rc = UADSetByteOrder(this, "MSB");       /* irrelevant */
2729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            rc = UADSetNumberFormat(this, "SIGNED");
2739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            break;
2749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        case AUDIO_S16LSB:
2759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	    success       = 1;
2769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            bitsPerSample = 16;
2779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            rc = UADSetSampleRate(this,  spec->freq << 16, &outRate );
2789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            rc = UADSetByteOrder(this, "LSB");
2799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            rc = UADSetNumberFormat(this, "SIGNED");
2809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            break;
2819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        case AUDIO_S16MSB:
2829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	    success       = 1;
2839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            bitsPerSample = 16;
2849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            rc = UADSetSampleRate(this,  spec->freq << 16, &outRate );
2859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            rc = UADSetByteOrder(this, "MSB");
2869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            rc = UADSetNumberFormat(this, "SIGNED");
2879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            break;
2889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        case AUDIO_U16LSB:
2899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	    success       = 1;
2909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            bitsPerSample = 16;
2919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            rc = UADSetSampleRate(this,  spec->freq << 16, &outRate );
2929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            rc = UADSetByteOrder(this, "LSB");
2939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            rc = UADSetNumberFormat(this, "UNSIGNED");
2949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            break;
2959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        case AUDIO_U16MSB:
2969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	    success       = 1;
2979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            bitsPerSample = 16;
2989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            rc = UADSetSampleRate(this,  spec->freq << 16, &outRate );
2999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            rc = UADSetByteOrder(this, "MSB");
3009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            rc = UADSetNumberFormat(this, "UNSIGNED");
3019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            break;
3029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        default:
3039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            break;
3049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        }
3059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        if ( ! success ) {
3069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            test_format = SDL_NextAudioFormat();
3079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        }
3089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    }
3099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    while ( ! success && test_format );
3109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
3119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    if ( success == 0 ) {
3129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        SDL_SetError("Couldn't find any hardware audio formats");
3139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        return -1;
3149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    }
3159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
3169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    spec->format = test_format;
3179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
3189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    for ( frag_spec = 0; (0x01<<frag_spec) < spec->size; ++frag_spec );
3199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    if ( (0x01<<frag_spec) != spec->size ) {
3209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        SDL_SetError("Fragment size must be a power of two");
3219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        return -1;
3229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    }
3239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    if ( frag_spec > 2048 ) frag_spec = 2048;
3249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
3259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    this->hidden->bytesPerSample   = (bitsPerSample / 8) * spec->channels;
3269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    samplesPerSec                  = this->hidden->bytesPerSample * outRate;
3279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
3289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    this->hidden->playbuf._length  = 0;
3299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    this->hidden->playbuf._maximum = spec->size;
3309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    this->hidden->playbuf._buffer  = (unsigned char*)SDL_malloc(spec->size);
3319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    this->hidden->fillbuf._length  = 0;
3329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    this->hidden->fillbuf._maximum = spec->size;
3339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    this->hidden->fillbuf._buffer  = (unsigned char*)SDL_malloc(spec->size);
3349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
3359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    rc = UADSetBitsPerSample(this,  bitsPerSample );
3369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    rc = UADSetDMABufferSize(this,  frag_spec, &outBufSize );
3379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    rc = UADSetChannels(this, spec->channels);      /* functions reduces to mono or stereo */
3389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
3399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    lgain = 100; /*maximum left input gain*/
3409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    rgain = 100; /*maimum right input gain*/
3419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    rc = UADEnableOutput(this, "LINE_OUT",&lgain,&rgain);
3429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    rc = UADInitialize(this);
3439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    rc = UADStart(this);
3449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    rc = UADSetVolume(this, 100);
3459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    rc = UADSetBalance(this, 0);
3469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
3479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /* We're ready to rock and roll. :-) */
3489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return 0;
3499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
3509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
3519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
3529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADGetBitsPerSample(_THIS, long* bits)
3539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
3549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_get_bits_per_sample( this->hidden->umsdev,
3559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					       this->hidden->ev,
3569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					       bits );
3579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
3589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
3599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetBitsPerSample(_THIS, long bits)
3609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
3619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_set_bits_per_sample( this->hidden->umsdev,
3629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					       this->hidden->ev,
3639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					       bits );
3649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
3659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
3669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetSampleRate(_THIS, long rate, long* set_rate)
3679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
3689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /* from the mac code: sample rate = spec->freq << 16; */
3699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_set_sample_rate( this->hidden->umsdev,
3709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					   this->hidden->ev,
3719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					   rate,
3729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					   set_rate );
3739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
3749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
3759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetByteOrder(_THIS, string byte_order)
3769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
3779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_set_byte_order( this->hidden->umsdev,
3789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					  this->hidden->ev,
3799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					  byte_order );
3809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
3819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
3829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetAudioFormatType(_THIS, string fmt)
3839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
3849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /* possible PCM, A_LAW or MU_LAW */
3859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_set_audio_format_type( this->hidden->umsdev,
3869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall						 this->hidden->ev,
3879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall						 fmt );
3889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
3899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
3909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetNumberFormat(_THIS, string fmt)
3919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
3929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /* possible SIGNED, UNSIGNED, or TWOS_COMPLEMENT */
3939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_set_number_format( this->hidden->umsdev,
3949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					     this->hidden->ev,
3959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					     fmt );
3969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
3979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
3989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADInitialize(_THIS)
3999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
4009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_initialize( this->hidden->umsdev,
4019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				      this->hidden->ev );
4029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
4039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
4049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADStart(_THIS)
4059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
4069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_start( this->hidden->umsdev,
4079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				 this->hidden->ev );
4089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
4099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
4109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetTimeFormat(_THIS,  UMSAudioTypes_TimeFormat fmt )
4119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
4129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /*
4139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * Switches the time format to the new format, immediately.
4149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * possible UMSAudioTypes_Msecs, UMSAudioTypes_Bytes or UMSAudioTypes_Samples
4159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     */
4169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_set_time_format( this->hidden->umsdev,
4179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					   this->hidden->ev,
4189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					   fmt );
4199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
4209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
4219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADWriteBuffSize(_THIS,  long* buff_size )
4229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
4239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /*
4249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * returns write buffer size in the current time format
4259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     */
4269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_write_buff_size( this->hidden->umsdev,
4279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall                                           this->hidden->ev,
4289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					   buff_size );
4299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
4309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
4319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADWriteBuffRemain(_THIS,  long* buff_size )
4329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
4339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /*
4349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * returns amount of available space in the write buffer
4359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * in the current time format
4369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     */
4379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_write_buff_remain( this->hidden->umsdev,
4389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall                                             this->hidden->ev,
4399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					     buff_size );
4409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
4419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
4429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADWriteBuffUsed(_THIS,  long* buff_size )
4439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
4449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /*
4459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * returns amount of filled space in the write buffer
4469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * in the current time format
4479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     */
4489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_write_buff_used( this->hidden->umsdev,
4499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall                                           this->hidden->ev,
4509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					   buff_size );
4519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
4529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
4539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetDMABufferSize(_THIS,  long bytes, long* bytes_ret )
4549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
4559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /*
4569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * Request a new DMA buffer size, maximum requested size 2048.
4579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * Takes effect with next initialize() call.
4589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * Devices may or may not support DMA.
4599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     */
4609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_set_DMA_buffer_size( this->hidden->umsdev,
4619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					       this->hidden->ev,
4629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					       bytes,
4639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					       bytes_ret );
4649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
4659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
4669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetVolume(_THIS,  long volume )
4679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
4689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /*
4699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * Set the volume.
4709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * Takes effect immediately.
4719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     */
4729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_set_volume( this->hidden->umsdev,
4739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				      this->hidden->ev,
4749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				      volume );
4759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
4769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
4779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetBalance(_THIS,  long balance )
4789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
4799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /*
4809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * Set the balance.
4819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * Takes effect immediately.
4829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     */
4839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_set_balance( this->hidden->umsdev,
4849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				       this->hidden->ev,
4859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				       balance );
4869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
4879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
4889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADSetChannels(_THIS,  long channels )
4899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
4909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    /*
4919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * Set mono or stereo.
4929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     * Takes effect with next initialize() call.
4939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall     */
4949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    if ( channels != 1 ) channels = 2;
4959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_set_number_of_channels( this->hidden->umsdev,
4969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				                  this->hidden->ev,
4979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				                  channels );
4989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
4999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
5009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADOpen(_THIS,  string device, string mode, long flags)
5019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
5029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_open( this->hidden->umsdev,
5039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				this->hidden->ev,
5049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				device,
5059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				mode,
5069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				flags );
5079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
5089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
5099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADWrite(_THIS,  UMSAudioTypes_Buffer* buff,
5109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall                                           long samples,
5119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					   long* samples_written)
5129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
5139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_write( this->hidden->umsdev,
5149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				 this->hidden->ev,
5159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				 buff,
5169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				 samples,
5179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				 samples_written );
5189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
5199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
5209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADPlayRemainingData(_THIS,  boolean block )
5219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
5229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_play_remaining_data( this->hidden->umsdev,
5239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					       this->hidden->ev,
5249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					       block);
5259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
5269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
5279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADStop(_THIS)
5289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
5299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_stop( this->hidden->umsdev,
5309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				this->hidden->ev );
5319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
5329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
5339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADClose(_THIS)
5349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
5359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_close( this->hidden->umsdev,
5369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				 this->hidden->ev );
5379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
5389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
5399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic UMSAudioDevice_ReturnCode UADEnableOutput(_THIS,  string output, long* left_gain, long* right_gain)
5409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
5419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    return UMSAudioDevice_enable_output( this->hidden->umsdev,
5429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					 this->hidden->ev,
5439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					 output,
5449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					 left_gain,
5459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					 right_gain );
5469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
5479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
548