1 /* SDL Driver for P.E.Op.S Sound Plugin
2 * Copyright (c) 2010, Wei Mingzhi <whistler_wmz@users.sf.net>.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA
23 #define BUFFER_SIZE 22050
25 short *pSndBuffer = NULL;
27 volatile int iReadPos = 0, iWritePos = 0;
29 static void SOUND_FillAudio(void *unused, Uint8 *stream, int len) {
30 short *p = (short *)stream;
34 while (iReadPos != iWritePos && len > 0) {
35 *p++ = pSndBuffer[iReadPos++];
36 if (iReadPos >= iBufSize) iReadPos = 0;
40 // Fill remaining space with zero
47 static void InitSDL() {
48 if (SDL_WasInit(SDL_INIT_EVERYTHING)) {
49 SDL_InitSubSystem(SDL_INIT_AUDIO);
51 SDL_Init(SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE);
55 static void DestroySDL() {
56 if (SDL_WasInit(SDL_INIT_EVERYTHING & ~SDL_INIT_AUDIO)) {
57 SDL_QuitSubSystem(SDL_INIT_AUDIO);
63 static int sdl_init(void) {
66 if (pSndBuffer != NULL) return -1;
71 spec.format = AUDIO_S16SYS;
74 spec.callback = SOUND_FillAudio;
76 if (SDL_OpenAudio(&spec, NULL) < 0) {
81 iBufSize = BUFFER_SIZE;
83 pSndBuffer = (short *)malloc(iBufSize * sizeof(short));
84 if (pSndBuffer == NULL) {
96 static void sdl_finish(void) {
97 if (pSndBuffer == NULL) return;
106 static int sdl_busy(void) {
109 if (pSndBuffer == NULL) return 1;
111 size = iReadPos - iWritePos;
112 if (size <= 0) size += iBufSize;
114 if (size < iBufSize / 2) return 1;
119 static void sdl_feed(void *pSound, int lBytes) {
120 short *p = (short *)pSound;
122 if (pSndBuffer == NULL) return;
125 if (((iWritePos + 1) % iBufSize) == iReadPos) break;
127 pSndBuffer[iWritePos] = *p++;
130 if (iWritePos >= iBufSize) iWritePos = 0;
132 lBytes -= sizeof(short);
136 void out_register_sdl(struct out_driver *drv)
139 drv->init = sdl_init;
140 drv->finish = sdl_finish;
141 drv->busy = sdl_busy;
142 drv->feed = sdl_feed;