filename | src/drivers/audio_sdl.c |
changeset | 1161:d3511e94c29f |
prev | 1049:e723f379ec88 |
author | Nathan Keynes <nkeynes@lxdream.org> |
date | Sat Sep 17 22:39:36 2011 +1000 (12 years ago) |
permissions | -rw-r--r-- |
last change | Fix structure packing on v55 nero images (64-bit) Add basic support for track mode 16 (CDDA + subchannel data, 2448 bytes) |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 *
4 * The SDL sound driver
5 *
6 * Copyright (c) 2009 wahrhaft
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18 #include <stdio.h>
19 #include <unistd.h>
20 #include <SDL.h>
21 #include <SDL_audio.h>
22 #include "aica/audio.h"
23 #include "lxdream.h"
25 #define SDL_SAMPLES 512 //tweaking this value may help with audio dropouts
26 #define BYTES_PER_SAMPLE 4 //should be changed if samples are not S16 stereo
28 #define BUFFER_MIN_SIZE SDL_SAMPLES * BYTES_PER_SAMPLE * 4
29 #define BUFFER_MAX_SIZE SDL_SAMPLES * BYTES_PER_SAMPLE * 16
31 static char *audio_buffer;
32 static int buffer_pos;
34 static void mix_audio(void *userdata, Uint8 *stream, int len);
36 static gboolean audio_sdl_init( )
37 {
38 int rate = DEFAULT_SAMPLE_RATE;
39 int format = DEFAULT_SAMPLE_FORMAT;
41 SDL_AudioSpec fmt;
42 fmt.freq = rate;
43 if (format & AUDIO_FMT_16BIT)
44 fmt.format = AUDIO_S16;
45 else
46 fmt.format = AUDIO_U8;
47 if (format & AUDIO_FMT_STEREO)
48 fmt.channels = 2;
49 else
50 fmt.channels = 1;
52 fmt.samples = SDL_SAMPLES;
53 fmt.callback = mix_audio;
54 fmt.userdata = NULL;
56 if (SDL_OpenAudio(&fmt, NULL) < 0)
57 {
58 ERROR("Unable to open audio output (SDL)");
59 return FALSE;
60 }
61 buffer_pos = 0;
62 audio_buffer = (char*)malloc(BUFFER_MAX_SIZE * sizeof(char));
63 if (audio_buffer == NULL)
64 {
65 ERROR("Could not allocate audio buffer (SDL)");
66 return FALSE;
67 }
69 return TRUE;
70 }
72 gboolean audio_sdl_process_buffer( audio_buffer_t buffer )
73 {
74 SDL_LockAudio();
75 if (buffer_pos + buffer->length >= BUFFER_MAX_SIZE)
76 {
77 DEBUG("Audio buffer full, dropping a chunk\n");
78 }
79 else
80 {
81 memcpy(audio_buffer, buffer->data, buffer->length);
82 buffer_pos += buffer->length;
83 }
84 SDL_UnlockAudio();
86 return TRUE;
87 }
89 static void mix_audio(void *userdata, Uint8 *stream, int len)
90 {
91 if (len < buffer_pos)
92 {
93 memcpy(stream, audio_buffer, len);
94 }
95 if (buffer_pos > BUFFER_MIN_SIZE)
96 {
97 memcpy(audio_buffer, &audio_buffer[len], buffer_pos - len);
98 buffer_pos -= len;
99 }
100 else
101 {
102 DEBUG("Audio buffer low, repeating a chunk\n");
103 }
104 }
106 static gboolean audio_sdl_shutdown()
107 {
108 SDL_CloseAudio();
109 free(audio_buffer);
110 return TRUE;
111 }
113 static void audio_sdl_start()
114 {
115 SDL_PauseAudio(0);
116 }
118 static void audio_sdl_stop()
119 {
120 SDL_PauseAudio(1);
121 }
123 static struct audio_driver audio_sdl_driver = {
124 "sdl",
125 N_("SDL sound driver"),
126 20,
127 DEFAULT_SAMPLE_RATE,
128 DEFAULT_SAMPLE_FORMAT,
129 audio_sdl_init,
130 audio_sdl_start,
131 audio_sdl_process_buffer,
132 audio_sdl_stop,
133 audio_sdl_shutdown
134 };
136 AUDIO_DRIVER( "sdl", audio_sdl_driver );
.