dsl.c

来自「An interactive water fountain. A realis」· C语言 代码 · 共 281 行

C
281
字号
/*Copyright (C) 2003-2004 Ryan C. Gordon. and James BentlerThis program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.Originally written by Ryan C. Gordon. (icculus@clutteredmind.org)Adapted to work with JonoF's port by James Bentler (bentler@cs.umn.edu)*/#include <stdlib.h>#include <string.h>#include "dsl.h"#include "compat.h"#include "pragmas.h"#define _NEED_SDLMIXER	1#include "sdl_inc.h"extern int32_t MV_MixPage;int32_t DSL_ErrorCode = DSL_Ok;static int32_t mixer_initialized;static int32_t interrupts_disabled = 0;static int32_t(*_DSL_CallBackFunc)(int32_t);static volatile char *_DSL_BufferStart;static int32_t _DSL_BufferSize;static int32_t _DSL_SampleRate;static int32_t _DSL_remainder;static Uint16 _DSL_format;static int32_t _DSL_channels;static Mix_Chunk *blank;static uint8_t *blank_buf;/*possible todo ideas: cache sdl/sdl mixer error messages.*/char *DSL_ErrorString(int32_t ErrorNumber){    char *ErrorString;    switch (ErrorNumber)    {    case DSL_Warning:    case DSL_Error:        ErrorString = DSL_ErrorString(DSL_ErrorCode);        break;    case DSL_Ok:        ErrorString = "SDL Driver ok.";        break;    case DSL_SDLInitFailure:        ErrorString = "SDL Audio initialization failed.";        break;    case DSL_MixerActive:        ErrorString = "SDL Mixer already initialized.";        break;    case DSL_MixerInitFailure:        ErrorString = "SDL Mixer initialization failed.";        break;    default:        ErrorString = "Unknown SDL Driver error.";        break;    }    return ErrorString;}static void DSL_SetErrorCode(int32_t ErrorCode){    DSL_ErrorCode = ErrorCode;}int32_t DSL_Init(int32_t soundcard, int32_t mixrate, int32_t numchannels, int32_t samplebits, int32_t buffersize){    /* FIXME: Do I need an SDL_mixer version check     * like that in sdlmusic.h here, too???     */    UNREFERENCED_PARAMETER(soundcard);    UNREFERENCED_PARAMETER(buffersize);    DSL_SetErrorCode(DSL_Ok);    if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)    {        DSL_SetErrorCode(DSL_SDLInitFailure);        return DSL_Error;    }    _DSL_channels = numchannels;    _DSL_SampleRate = mixrate;    _DSL_format = (samplebits == 16) ? AUDIO_S16SYS : AUDIO_U8;    return DSL_Ok;}void DSL_Shutdown(void){    DSL_StopPlayback();}static void mixer_callback(int32_t chan, void *stream, int32_t len, void *udata){    Uint8 *stptr;    Uint8 *fxptr;    int32_t copysize;    UNREFERENCED_PARAMETER(chan);    UNREFERENCED_PARAMETER(udata);    /* len should equal _DSL_BufferSize, else this is screwed up */    stptr = (Uint8 *)stream;    if (_DSL_remainder > 0)    {        copysize = min(len, _DSL_remainder);        fxptr = (Uint8 *)(&_DSL_BufferStart[MV_MixPage *                                        _DSL_BufferSize]);        memcpy(stptr, fxptr+(_DSL_BufferSize-_DSL_remainder), copysize);        len -= copysize;        _DSL_remainder -= copysize;        stptr += copysize;    }    while (len > 0)    {        /* new buffer */        _DSL_CallBackFunc(0);        fxptr = (Uint8 *)(&_DSL_BufferStart[MV_MixPage *                                        _DSL_BufferSize]);        copysize = min(len, _DSL_BufferSize);        memcpy(stptr, fxptr, copysize);        len -= copysize;        stptr += copysize;    }    _DSL_remainder = len;}//int32_t   DSL_BeginBufferedPlayback(char *BufferStart,  //                              int32_t BufferSize, int32_t NumDivisions, unsigned SampleRate,    //                            int32_t MixMode, void(*CallBackFunc)(void))int32_t DSL_BeginBufferedPlayback(char *BufferStart, int32_t(*CallBackFunc)(int32_t), int32_t BufferSize, int32_t NumDivisions){    int32_t chunksize;    if (mixer_initialized)    {        DSL_SetErrorCode(DSL_MixerActive);        return DSL_Error;    }    _DSL_CallBackFunc = CallBackFunc;    _DSL_BufferStart = BufferStart;    _DSL_BufferSize = (BufferSize / NumDivisions);        _DSL_remainder = 0;    /*       23ms is typically ideal (11025,22050,44100)       46ms isn't bad    */    chunksize = 512;    if (_DSL_SampleRate >= 16000) chunksize *= 2;    if (_DSL_SampleRate >= 32000) chunksize *= 2;    if (Mix_OpenAudio(_DSL_SampleRate, _DSL_format, _DSL_channels, chunksize) < 0)    {        DSL_SetErrorCode(DSL_MixerInitFailure);        return DSL_Error;    }    /*       Mix_SetPostMix(mixer_callback, NULL);    */    /* have to use a channel because postmix will overwrite the music... */    Mix_RegisterEffect(0, mixer_callback, NULL, NULL);    /* create a dummy sample just to allocate that channel */    blank_buf = (Uint8 *)malloc(4096);    memset(blank_buf, 0, 4096);    blank = Mix_QuickLoad_RAW(blank_buf, 4096);    Mix_PlayChannel(0, blank, -1);    mixer_initialized = 1;    return DSL_Ok;}void DSL_StopPlayback(void){    if (mixer_initialized)    {        Mix_HaltChannel(0);    }    if (blank != NULL)    {        Mix_FreeChunk(blank);    }    blank = NULL;    if (blank_buf  != NULL)    {        free(blank_buf);    }    blank_buf = NULL;    if (mixer_initialized)    {        Mix_CloseAudio();    }    mixer_initialized = 0;}unsigned DSL_GetPlaybackRate(void){    return _DSL_SampleRate;}int32_t DisableInterrupts(void){    if (interrupts_disabled++)        return 0;//    interrupts_disabled = 1;    SDL_LockAudio();    return(0);}int32_t RestoreInterrupts(int32_t flags){    UNREFERENCED_PARAMETER(flags);    if (--interrupts_disabled)        return 0;//   interrupts_disabled = 0;    SDL_UnlockAudio();    return(0);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?