📄 sdl_umsaudio.c
字号:
/* AIX support for the SDL - Simple DirectMedia Layer Copyright (C) 2000 Carsten Griwodz This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Carsten Griwodz griff@kom.tu-darmstadt.de based on linux/SDL_dspaudio.c by Sam Lantinga*/#ifdef SAVE_RCSIDstatic char rcsid = "@(#) $Id$";#endif/* Allow access to a raw mixing buffer */#include <stdlib.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <fcntl.h>#include <sys/types.h>#include <sys/time.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <sys/mman.h>#include "SDL_audio.h"#include "SDL_error.h"#include "SDL_audio_c.h"#include "SDL_audiodev_c.h"#include "SDL_umsaudio.h"/* The tag name used by UMS audio */#define UMS_DRIVER_NAME "ums"#define DEBUG_AUDIO 1/* Audio driver functions */static int UMS_OpenAudio(_THIS, SDL_AudioSpec *spec);static void UMS_PlayAudio(_THIS);static Uint8 *UMS_GetAudioBuf(_THIS);static void UMS_CloseAudio(_THIS);static UMSAudioDevice_ReturnCode UADOpen(_THIS, string device, string mode, long flags);static UMSAudioDevice_ReturnCode UADClose(_THIS);static UMSAudioDevice_ReturnCode UADGetBitsPerSample(_THIS, long* bits);static UMSAudioDevice_ReturnCode UADSetBitsPerSample(_THIS, long bits);static UMSAudioDevice_ReturnCode UADSetSampleRate(_THIS, long rate, long* set_rate);static UMSAudioDevice_ReturnCode UADSetByteOrder(_THIS, string byte_order);static UMSAudioDevice_ReturnCode UADSetAudioFormatType(_THIS, string fmt);static UMSAudioDevice_ReturnCode UADSetNumberFormat(_THIS, string fmt);static UMSAudioDevice_ReturnCode UADInitialize(_THIS);static UMSAudioDevice_ReturnCode UADStart(_THIS);static UMSAudioDevice_ReturnCode UADStop(_THIS);static UMSAudioDevice_ReturnCode UADSetTimeFormat(_THIS, UMSAudioTypes_TimeFormat fmt );static UMSAudioDevice_ReturnCode UADWriteBuffSize(_THIS, long* buff_size );static UMSAudioDevice_ReturnCode UADWriteBuffRemain(_THIS, long* buff_size );static UMSAudioDevice_ReturnCode UADWriteBuffUsed(_THIS, long* buff_size );static UMSAudioDevice_ReturnCode UADSetDMABufferSize(_THIS, long bytes, long* bytes_ret );static UMSAudioDevice_ReturnCode UADSetVolume(_THIS, long volume );static UMSAudioDevice_ReturnCode UADSetBalance(_THIS, long balance );static UMSAudioDevice_ReturnCode UADSetChannels(_THIS, long channels );static UMSAudioDevice_ReturnCode UADPlayRemainingData(_THIS, boolean block );static UMSAudioDevice_ReturnCode UADEnableOutput(_THIS, string output, long* left_gain, long* right_gain);static UMSAudioDevice_ReturnCode UADWrite(_THIS, UMSAudioTypes_Buffer* buff, long samples, long* samples_written);/* Audio driver bootstrap functions */static int Audio_Available(void){ return 1;}static void Audio_DeleteDevice(_THIS){ if(this->hidden->playbuf._buffer) free(this->hidden->playbuf._buffer); if(this->hidden->fillbuf._buffer) free(this->hidden->fillbuf._buffer); _somFree( this->hidden->umsdev ); free(this->hidden); free(this);}static SDL_AudioDevice *Audio_CreateDevice(int devindex){ SDL_AudioDevice *this; /* * Allocate and initialize management storage and private management * storage for this SDL-using library. */ this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice)); if ( this ) { memset(this, 0, (sizeof *this)); this->hidden = (struct SDL_PrivateAudioData *)malloc((sizeof *this->hidden)); } if ( (this == NULL) || (this->hidden == NULL) ) { SDL_OutOfMemory(); if ( this ) { free(this); } return(0); } memset(this->hidden, 0, (sizeof *this->hidden));#ifdef DEBUG_AUDIO fprintf(stderr, "Creating UMS Audio device\n");#endif /* * Calls for UMS env initialization and audio object construction. */ this->hidden->ev = somGetGlobalEnvironment(); this->hidden->umsdev = UMSAudioDeviceNew(); /* * Set the function pointers. */ this->OpenAudio = UMS_OpenAudio; this->WaitAudio = NULL; /* we do blocking output */ this->PlayAudio = UMS_PlayAudio; this->GetAudioBuf = UMS_GetAudioBuf; this->CloseAudio = UMS_CloseAudio; this->free = Audio_DeleteDevice;#ifdef DEBUG_AUDIO fprintf(stderr, "done\n");#endif return this;}AudioBootStrap UMS_bootstrap = { UMS_DRIVER_NAME, "AUX UMS audio", Audio_Available, Audio_CreateDevice};static Uint8 *UMS_GetAudioBuf(_THIS){#ifdef DEBUG_AUDIO fprintf(stderr, "enter UMS_GetAudioBuf\n");#endif return this->hidden->fillbuf._buffer;/* long bufSize; UMSAudioDevice_ReturnCode rc; rc = UADSetTimeFormat(this, UMSAudioTypes_Bytes ); rc = UADWriteBuffSize(this, bufSize );*/}static void UMS_CloseAudio(_THIS){ UMSAudioDevice_ReturnCode rc;#ifdef DEBUG_AUDIO fprintf(stderr, "enter UMS_CloseAudio\n");#endif rc = UADPlayRemainingData(this, TRUE); rc = UADStop(this); rc = UADClose(this);}static void UMS_PlayAudio(_THIS){ UMSAudioDevice_ReturnCode rc; long samplesToWrite; long samplesWritten; UMSAudioTypes_Buffer swpbuf;#ifdef DEBUG_AUDIO fprintf(stderr, "enter UMS_PlayAudio\n");#endif samplesToWrite = this->hidden->playbuf._length/this->hidden->bytesPerSample; do { rc = UADWrite(this, &this->hidden->playbuf, samplesToWrite, &samplesWritten ); samplesToWrite -= samplesWritten; /* rc values: UMSAudioDevice_Success * UMSAudioDevice_Failure * UMSAudioDevice_Preempted * UMSAudioDevice_Interrupted * UMSAudioDevice_DeviceError */ if ( rc == UMSAudioDevice_DeviceError ) {#ifdef DEBUG_AUDIO fprintf(stderr, "Returning from PlayAudio with devices error\n");#endif return; } } while(samplesToWrite>0); SDL_LockAudio(); memcpy( &swpbuf, &this->hidden->playbuf, sizeof(UMSAudioTypes_Buffer) ); memcpy( &this->hidden->playbuf, &this->hidden->fillbuf, sizeof(UMSAudioTypes_Buffer) ); memcpy( &this->hidden->fillbuf, &swpbuf, sizeof(UMSAudioTypes_Buffer) ); SDL_UnlockAudio();#ifdef DEBUG_AUDIO fprintf(stderr, "Wrote audio data and swapped buffer\n");#endif}#if 0// /* Set the DSP frequency */// value = spec->freq;// if ( ioctl(this->hidden->audio_fd, SOUND_PCM_WRITE_RATE, &value) < 0 ) {// SDL_SetError("Couldn't set audio frequency");// return(-1);// }// spec->freq = value;#endifstatic int UMS_OpenAudio(_THIS, SDL_AudioSpec *spec){ char* audiodev = "/dev/paud0"; long lgain; long rgain; long outRate; long outBufSize; long bitsPerSample; long samplesPerSec; long success; Uint16 test_format; int frag_spec; UMSAudioDevice_ReturnCode rc;#ifdef DEBUG_AUDIO fprintf(stderr, "enter UMS_OpenAudio\n");#endif rc = UADOpen(this, audiodev,"PLAY", UMSAudioDevice_BlockingIO); if ( rc != UMSAudioDevice_Success ) { SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); return -1; } rc = UADSetAudioFormatType(this, "PCM"); success = 0; test_format = SDL_FirstAudioFormat(spec->format); do {#ifdef DEBUG_AUDIO fprintf(stderr, "Trying format 0x%4.4x\n", test_format);#endif switch ( test_format ) { case AUDIO_U8:/* from the mac code: better ? *//* sample_bits = spec->size / spec->samples / spec->channels * 8; */ success = 1; bitsPerSample = 8; rc = UADSetSampleRate(this, spec->freq << 16, &outRate ); rc = UADSetByteOrder(this, "MSB"); /* irrelevant */ rc = UADSetNumberFormat(this, "UNSIGNED"); break; case AUDIO_S8: success = 1; bitsPerSample = 8; rc = UADSetSampleRate(this, spec->freq << 16, &outRate );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -