Sisyphus repositório
Última atualização: 1 outubro 2023 | SRPMs: 18631 | Visitas: 37778269
en ru br
ALT Linux repositórios
S:20050826-alt4
5.0: 20050826-alt2
4.1: 20050826-alt2
4.0: 20050826-alt2
3.0: 20041117-alt1

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


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;
 }
 
projeto & código: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
mantenedor atual: Michael Shigorin
mantenedor da tradução: Fernando Martini aka fmartini © 2009