ALT Linux repositórios
Group :: Emuladores
RPM: bk
Main Changelog Spec Patches Sources Download Gear Bugs e FR Repocop
Patch: bk-terak-emu.2005.08.26-linuxsound.diff
Download
Download
diff -Nru bk-terak-emu.2005.08.26/main.c bk/main.c
--- bk-terak-emu.2005.08.26/main.c 2005-05-21 11:19:07 +0400
+++ bk/main.c 2004-11-17 11:44:22 +0300
@@ -195,7 +194,7 @@
printf( _("Initializing SDL.\n") );
- if((SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER)==-1)) {
+ if((SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_TIMER)==-1)) {
printf( _("Could not initialize SDL: %s.\n"), SDL_GetError());
exit(-1);
}
diff -Nru bk-terak-emu.2005.08.26/sound.c bk/sound.c
--- bk-terak-emu.2005.08.26/sound.c 2005-06-25 20:59:30 +0400
+++ bk/sound.c 2004-11-17 10:50:17 +0300
@@ -3,17 +3,20 @@
#include <SDL/SDL.h>
#include <SDL/SDL_thread.h>
#include <SDL/SDL_mutex.h>
+#include <linux/soundcard.h>
#include <libintl.h>
#define _(String) gettext (String)
-#define SOUND_EXPONENT (8+io_sound_freq/20000)
+#define SOUND_FREQ 44100
+#define SOUND_EXPONENT 10
#define SOUND_BUFSIZE (1<<SOUND_EXPONENT) /* about 1/43 sec */
+#define SOUND_FRAGMENTS 3
#define MAX_SOUND_AGE ~0 /* always play */
unsigned io_max_sound_age = MAX_SOUND_AGE;
unsigned io_sound_age = MAX_SOUND_AGE; /* in io_sound_pace's since last change */
-unsigned io_sound_bufsize,
- io_sound_freq = 11025,
+unsigned io_sound_bufsize = SOUND_BUFSIZE,
+ io_sound_freq = SOUND_FREQ,
io_sound_pace;
double io_sound_count;
extern unsigned io_sound_val, covox_age;
@@ -23,28 +26,33 @@
typedef struct {
short * buf;
unsigned int ptr;
-} sound_buf_t;
+ SDL_mutex * lock;
-#define NUMBUF 2
+} sound_buf_t;
-sound_buf_t sound_buf[NUMBUF];
+sound_buf_t sound_buf[2];
-SDL_sem * sem;
-
int cur_buf;
-void callback(void * dummy, Uint8 * outbuf, int len)
+int io_sound_fd = -1;
+
+#ifdef THREADED
+int write_buffer(void * dummy)
{
- static int cur_out_buf;
- if (SDL_SemValue(sem) == NUMBUF) {
- // Underflow: TODO fill the buffer with silence
- // fprintf(stderr, "!");
- return;
- }
- memcpy(outbuf, sound_buf[cur_out_buf].buf, len);
- cur_out_buf = (cur_out_buf + 1) % NUMBUF;
- SDL_SemPost(sem);
+ while (1) {
+ SDL_mutexP(sound_buf[0].lock);
+ if (io_sound_fd == -1) return 0;
+ write(io_sound_fd, sound_buf[0].buf, sound_buf[0].ptr*sizeof(short));
+ sound_buf[0].ptr = 0;
+ SDL_mutexV(sound_buf[0].lock);
+ SDL_mutexP(sound_buf[1].lock);
+ if (io_sound_fd == -1) return 0;
+ write(io_sound_fd, sound_buf[1].buf, sound_buf[1].ptr*sizeof(short));
+ sound_buf[1].ptr = 0;
+ SDL_mutexV(sound_buf[1].lock);
+ }
}
+#endif
/* Called after every instruction */
sound_flush() {
@@ -54,11 +62,10 @@
* matter.
*/
if (sound_buf[cur_buf].ptr != 0) {
- // TODO: Fill up the buffer with silence
- // Give the buffer to the callback
- SDL_SemWait(sem);
+ write(io_sound_fd, sound_buf[cur_buf].buf, sound_buf[cur_buf].ptr * sizeof(short));
+ ioctl(io_sound_fd, SNDCTL_DSP_POST);
sound_buf[cur_buf].ptr = 0;
- cur_buf = (cur_buf + 1) % NUMBUF;
+ cur_buf = !cur_buf;
}
return;
}
@@ -74,29 +81,34 @@
covox_age++;
if (io_sound_bufsize == sound_buf[cur_buf].ptr ||
io_sound_age == io_max_sound_age) {
- SDL_SemWait(sem);
+#ifdef THREADED
+ /* lock the other buffer first */
+ SDL_mutexP(sound_buf[!cur_buf].lock);
+ /* release current buffer to be played */
+ SDL_mutexV(sound_buf[cur_buf].lock);
+#else
+ write(io_sound_fd, sound_buf[cur_buf].buf, sound_buf[cur_buf].ptr * sizeof(short));
sound_buf[cur_buf].ptr = 0;
- cur_buf = (cur_buf + 1) % NUMBUF;
+#endif
+ cur_buf = !cur_buf;
}
}
}
void sound_finish() {
+ io_sound_fd = -1;
/* release the write thread so it can terminate */
- SDL_PauseAudio(1);
- SDL_DestroySemaphore(sem);
+ SDL_mutexV(sound_buf[cur_buf].lock);
}
-SDL_AudioSpec desired;
-
sound_init() {
static init_done = 0;
- int iarg, i;
+ int iarg;
if (!nflag)
return;
if (fullspeed) {
- io_max_sound_age = 2 * SOUND_BUFSIZE;
+ io_max_sound_age = SOUND_FRAGMENTS * SOUND_BUFSIZE;
/* otherwise UINT_MAX */
}
if (init_done) {
@@ -106,33 +118,67 @@
}
fprintf(stderr, _("sound_init called\n"));
- if (-1 == SDL_InitSubSystem(SDL_INIT_AUDIO)) {
- fprintf(stderr, _("Failed to initialize audio subsystem\n"));
+ fprintf(stderr, _("Opening audio... "));
+ io_sound_fd = open("/dev/dsp", O_WRONLY);
+ if (-1 != io_sound_fd) {
+ fprintf(stderr, _("Done.\n"));
+ } else {
+ perror("/dev/dsp");
+ }
+
+ int fmt = 16;
+ if (-1 == ioctl(io_sound_fd, SNDCTL_DSP_SETFMT, &fmt)) {
+ perror(_("Setting 16-bit sound failed"));
+ }
+ fmt = 1;
+ if (-1 == ioctl(io_sound_fd, SNDCTL_DSP_CHANNELS, &fmt)) {
+ perror(_("Setting mono sound failed"));
+ }
+
+ /* Setting desired frequency */
+ ioctl(io_sound_fd, SNDCTL_DSP_SPEED, &io_sound_freq);
+ if (io_sound_freq != SOUND_FREQ) {
+ fprintf(stderr, _("Warning: %s doesn't support default sample rate of %d (set to %d)\n"), "/dev/dsp", SOUND_FREQ, io_sound_freq);
}
+ io_sound_pace = TICK_RATE/io_sound_freq;
- desired.format = 16;
- desired.channels = 1;
- desired.freq = io_sound_freq;
- desired.samples = io_sound_bufsize = SOUND_BUFSIZE;
- desired.callback = callback;
- if (-1 == SDL_OpenAudio(&desired, 0)) {
- fprintf(stderr, _("Failed to initialize sound, freq %d, %d samples\n"), io_sound_freq, SOUND_BUFSIZE);
- nflag = 0;
- return;
+ /* Setting desired buffering parameters: 3 buffers, 1 Kb each */
+ iarg = (SOUND_FRAGMENTS << 16) | SOUND_EXPONENT;
+ if (ioctl(io_sound_fd, SNDCTL_DSP_SETFRAGMENT, &iarg) == -1) {
+ perror(_("/dev/dsp: setfragment failed"));
+ exit(1);
}
- io_sound_pace = TICK_RATE/io_sound_freq;
- sem = SDL_CreateSemaphore(NUMBUF);
-
- for (i = 0; i < NUMBUF; i++) {
- sound_buf[i].ptr = 0;
- sound_buf[i].buf = malloc(io_sound_bufsize * sizeof(short));
+ /* Checking what we've got */
+ if (ioctl(io_sound_fd, SNDCTL_DSP_GETBLKSIZE, &io_sound_bufsize) == -1) {
+ perror(_("/dev/dsp: getbksize failed"));
+ exit(1);
+ }
+ if (io_sound_bufsize != SOUND_BUFSIZE) {
+ fprintf(stderr, _("Warning: asked for sound delay 1/%d sec, got 1/%d sec\n"),
+ io_sound_freq/SOUND_BUFSIZE, io_sound_freq/io_sound_bufsize);
+
+ /* We may want to rerequest more fragments by closing
+ * /dev/dsp and restarting sound_init(), but let's hope
+ * that current computers are fast enough.
+ */
+ if (io_sound_freq/io_sound_bufsize > 100) {
+ fprintf(stderr, _("Warning: sound quality may be low\n"));
+ }
}
- if (!sound_buf[NUMBUF-1].buf) {
+ sound_buf[0].ptr = sound_buf[1].ptr = 0;
+ sound_buf[0].buf = malloc(io_sound_bufsize * sizeof(short));
+ sound_buf[1].buf = malloc(io_sound_bufsize * sizeof(short));
+ if (!sound_buf[1].buf) {
fprintf(stderr, _("Failed to allocate sound buffers\n"));
exit(1);
}
+#ifdef THREADED
+ sound_buf[0].lock = SDL_CreateMutex();
+ sound_buf[1].lock = SDL_CreateMutex();
+ SDL_mutexP(sound_buf[0].lock);
+ SDL_CreateThread(write_buffer, 0); /* will immediately lock */
atexit(sound_finish);
- SDL_PauseAudio(0);
+#endif
init_done = 1;
}