📄 sdlaudio_drv.c
字号:
/*
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright(c) 2003-2006 Intel Corporation. All Rights Reserved.
//
*/
#include "umc_defs.h"
#ifdef UMC_ENABLE_SDL_AUDIO_RENDER
#include "sdlaudio_drv.h"
#include "vm_time.h"
#define SDLAUDIO_OK 0
#define SDLAUDIO_ERR -1
#define SDLAUDIO_OFF 0
#define SDLAUDIO_ON 1
#define SDLAUDIO_DELAY 10
void sdlaudioCallback(void *driver, Uint8 *stream, Ipp32s len);
static Ipp32s audio_data_remove(SDLAudioDrv *drv,
Ipp8u *data,
Ipp32s size);
static Ipp32s audio_data_add(SDLAudioDrv *drv,
Ipp8u *data,
Ipp32s size);
void *sdlaudioInit(const Ipp32u freq,
const Ipp32u channels,
const Ipp32u bps)
{
SDL_AudioSpec wanted_spec, spec;
Uint32 subsystems_init;
Ipp32u sSize = 0;
Ipp32s result = SDLAUDIO_OK;
SDLAudioDrv *drv =(SDLAudioDrv *)ippsMalloc_8u(sizeof(SDLAudioDrv));
/* Loading audio stream parameters to the drv structure. */
drv->mFrequency = freq;
drv->mChannels = channels;
drv->mBitPerSample = bps;
/* SDL audio subsystem initialization. */
subsystems_init = SDL_WasInit(SDL_INIT_EVERYTHING);
if (!subsystems_init)
result = SDL_Init(SDL_INIT_AUDIO);
else if (!(SDL_INIT_AUDIO & subsystems_init))
result = SDL_InitSubSystem(SDL_INIT_AUDIO);
if (SDLAUDIO_ERR == result)
{
vm_debug_trace(VM_DEBUG_NONE, VM_STRING("SDLAudio:" "Init:SDL_Init(SubSystem)" " FAILED"));
return NULL;
}
/* Some drv initialization. */
vm_mutex_set_invalid(&(drv->mLockSender));
result = vm_mutex_init(&(drv->mLockSender));
CHECK_RESULT(VM_OK, "Init:MutexInit", NULL)
vm_mutex_set_invalid(&(drv->mLockBuffer));
result = vm_mutex_init(&(drv->mLockBuffer));
CHECK_RESULT(VM_OK, "Init:MutexInit", NULL)
/* Setting SDL specification an opening audio device. */
wanted_spec.channels = (Uint8)drv->mChannels;
wanted_spec.freq = drv->mFrequency;
wanted_spec.format = SDLAUDIO_FORMAT;
wanted_spec.samples = SDLAUDIO_SAMPLES;
wanted_spec.userdata = drv;
wanted_spec.callback = sdlaudioCallback;
result = SDL_OpenAudio(&wanted_spec, &spec);
CHECK_RESULT(SDLAUDIO_OK, "Init:SDL_OpenAudio", NULL)
/* Audio unit frames buffer size check */
drv->mChunkSize = SDLAUDIO_BUFFERS_SIZE;
sSize = sizeof(drv->mChunkSize);
/* Buffers allocation and setup. */
drv->mChunksNumber = SDLAUDIO_BUFFERS_NUM;
drv->mBufferSize =(drv->mChunksNumber + 1) * drv->mChunkSize;
drv->mDataBuffer =(Ipp8u *)ippsMalloc_8u(drv->mBufferSize);
drv->mReadPosition = 0;
drv->mWritePosition = 0;
/* Starting audio processing */
SDL_PauseAudio (SDLAUDIO_OFF);
drv->mVolume = 1.0;
drv->mRenderFlag = SDLAUDIO_RENDER_OPEN;
return drv;
}
/**
* Add audio data to ringbuffer
*/
static Ipp32s audio_data_add(SDLAudioDrv *drv,
Ipp8u* data,
Ipp32s size)
{
Ipp32s offset, free;
if (NULL == drv) return size;
offset = drv->mBufferSize - drv->mWritePosition;
/* Number of free bytes in the buffer */
free = drv->mReadPosition - drv->mWritePosition - drv->mChunkSize;
if (free < 0) free += drv->mBufferSize;
if (size > free) size = free;
if (offset > size) offset = size;
/* Till end of buffer */
//memcpy(&drv->mDataBuffer[drv->mWritePosition], data, offset);
ippsCopy_8u(data, &drv->mDataBuffer[drv->mWritePosition], offset);
/* We have to wrap around */
if (size > offset)
{
/* remaining part from beginning of buffer */
//memcpy(drv->mDataBuffer, &data[offset], size - offset);
ippsCopy_8u(&data[offset], drv->mDataBuffer, size - offset);
}
drv->mWritePosition =(drv->mWritePosition + size) % drv->mBufferSize;
return size;
}
/**
* Remove data from ringbuffer
*/
static Ipp32s audio_data_remove(SDLAudioDrv *drv,
Ipp8u* data,
Ipp32s size)
{
Ipp32s offset, buffered;
if (NULL == drv) return size;
offset = drv->mBufferSize - drv->mReadPosition;
/* Number of buffered bytes */
buffered = drv->mWritePosition - drv->mReadPosition;
if (buffered < 0) buffered += drv->mBufferSize;
if (size > buffered) size = buffered;
if (offset > size) offset = size;
/* Till end of buffer */
//memcpy(data, &drv->mDataBuffer[drv->mReadPosition], offset);
//ippsCopy_8u(&drv->mDataBuffer[drv->mReadPosition], data, offset);
SDL_MixAudio(data, &drv->mDataBuffer[drv->mReadPosition], offset,
(Ipp32s)(drv->mVolume * SDL_MIX_MAXVOLUME));
/* We have to wrap around */
if (size > offset)
{
/* remaining part from beginning of buffer */
//memcpy(&data[offset], drv->mDataBuffer, size - offset);
//ippsCopy_8u(drv->mDataBuffer, &data[offset], size - offset);
SDL_MixAudio (&data[offset], drv->mDataBuffer, size - offset,
(Ipp32s)(drv->mVolume * SDL_MIX_MAXVOLUME));
}
drv->mReadPosition = (drv->mReadPosition + size) % drv->mBufferSize;
return size;
}
Ipp32s sdlaudioPlay(void *driver,
Ipp8u* buf,
Ipp32s size)
{
SDLAudioDrv *drv = (SDLAudioDrv *)driver;
Ipp32s added;
if (NULL == drv) return 0;
/*
* Eduard Martirosyan:
* This is a hack. Actualy we don't need to use mLockSender and mRenderFlag.
* But UMC run SendFrame() after Close(). Why?
*/
vm_mutex_lock(&(drv->mLockSender));
if (drv->mRenderFlag == SDLAUDIO_RENDER_OPEN)
{
while (size > 0)
{
vm_mutex_lock(&(drv->mLockBuffer));
added = audio_data_add(drv, buf, size);
vm_mutex_unlock(&(drv->mLockBuffer));
buf += added;
size -= added;
/* Increasing of productivity: */
if (size > 0) vm_time_sleep (SDLAUDIO_DELAY);
}
}
vm_mutex_unlock(&(drv->mLockSender));
return 0;
}
Ipp32s sdlaudioReset(void *driver)
{
SDLAudioDrv *drv =(SDLAudioDrv *)driver;
SDL_AudioSpec wanted_spec, spec;
SDL_audiostatus stat;
if (NULL == drv) return 0;
/* Reseting an audio device. */
SDL_LockAudio ();
stat = SDL_GetAudioStatus ();
SDL_PauseAudio (SDLAUDIO_ON);
SDL_UnlockAudio ();
SDL_CloseAudio ();
wanted_spec.channels = (Uint8)drv->mChannels;
wanted_spec.freq = drv->mFrequency;
wanted_spec.format = SDLAUDIO_FORMAT;
wanted_spec.samples = SDLAUDIO_SAMPLES;
wanted_spec.userdata = drv;
wanted_spec.callback = sdlaudioCallback;
SDL_OpenAudio(&wanted_spec, &spec);
drv->mReadPosition = 0;
drv->mWritePosition = 0;
if (stat == SDL_AUDIO_PLAYING) SDL_PauseAudio (SDLAUDIO_OFF);
else SDL_PauseAudio (SDLAUDIO_ON);
return 0;
}
Ipp32s sdlaudioPause(void *driver)
{
SDLAudioDrv *drv = (SDLAudioDrv *)driver;
if (NULL == drv) return 0;
/* Stopping audio processing */
SDL_LockAudio ();
SDL_PauseAudio (SDLAUDIO_ON);
SDL_UnlockAudio ();
return 0;
}
Ipp32s sdlaudioResume(void *driver)
{
SDLAudioDrv *drv = (SDLAudioDrv *)driver;
if (NULL == drv) return 0;
/* Starting audio processing */
SDL_LockAudio ();
SDL_PauseAudio (SDLAUDIO_OFF);
SDL_UnlockAudio ();
return 0;
}
Ipp32f sdlaudioSetVolume (void *driver, Ipp32f volume)
{
SDLAudioDrv *drv = (SDLAudioDrv *)driver;
if (NULL == drv) return 0;
if (volume < 0)
drv->mVolume = 0;
else if (volume > SDL_MIX_MAXVOLUME)
drv->mVolume = 1;
else
drv->mVolume = volume;
return drv->mVolume;
}
Ipp32f sdlaudioGetVolume (void *driver)
{
SDLAudioDrv *drv = (SDLAudioDrv *)driver;
if (NULL == drv) return 0;
return drv->mVolume;
}
void sdlaudioClose(void *driver)
{
SDLAudioDrv *drv = (SDLAudioDrv *)driver;
Uint32 subsystems_init;
if (NULL == drv) return;
vm_mutex_lock(&(drv->mLockSender));
vm_mutex_lock(&(drv->mLockBuffer));
drv->mRenderFlag = SDLAUDIO_RENDER_CLOSE;
/* Stopping audio processing. */
sdlaudioPause (driver);
SDL_CloseAudio ();
subsystems_init = SDL_WasInit(SDL_INIT_EVERYTHING);
if (SDL_INIT_EVERYTHING & (!SDL_INIT_AUDIO) & subsystems_init)
SDL_Quit();
else if (SDL_INIT_AUDIO & subsystems_init)
SDL_QuitSubSystem(SDL_INIT_AUDIO);
vm_mutex_unlock(&(drv->mLockSender));
vm_mutex_unlock(&(drv->mLockBuffer));
vm_mutex_destroy(&(drv->mLockBuffer));
vm_mutex_destroy(&(drv->mLockSender));
ippsFree(drv->mDataBuffer);
ippsFree(drv);
}
void sdlaudioCallback(void *driver, Uint8 *stream, Ipp32s len)
{
SDLAudioDrv *drv = (SDLAudioDrv *)driver;
Ipp32s buffered;
if (NULL == drv) return;
vm_mutex_lock(&(drv->mLockBuffer));
/* Number of buffered bytes */
buffered = drv->mWritePosition - drv->mReadPosition;
if (buffered < 0) buffered += drv->mBufferSize;
if (buffered > len) buffered = len;
if (buffered)
{
audio_data_remove(drv, (Ipp8u *)stream, buffered);
}
vm_mutex_unlock(&(drv->mLockBuffer));
}
#endif // UMC_ENABLE_SDL_AUDIO_RENDER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -