Hi,

I have been playing with getting sound to work for RPCEmu on Linux.  I
have attached a patch.

I have modified sound.c slightly, but have not tested it under Windows.
I see no reason why it should not work.

It seems OK, the occasional glitch.  I have played some Maestro files,
and Asylum.

Hope it is useful.

James

Index: rpcemu.c
===================================================================
--- rpcemu.c	(revision 132)
+++ rpcemu.c	(working copy)
@@ -105,8 +105,8 @@
 //printf("About to init video...\n");
         initvideo();
 //printf("Video inited!\n");
+        loadconfig();
         initsound();
-        loadconfig();
         reallocmem(rammask+1);
         initcodeblocks();
         iso_init();
Index: rpc-linux.c
===================================================================
--- rpc-linux.c	(revision 132)
+++ rpc-linux.c	(working copy)
@@ -14,14 +14,63 @@
 int mousecapture=0;
 float mips;
 int updatemips=0;
+int quited=0;
+pthread_t sound_thread;
+pthread_cond_t sound_cond = PTHREAD_COND_INITIALIZER;
+pthread_mutex_t sound_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 static uint32_t mipscount;
 float mipstotal;
 
+void *_soundthread(void *p)
+{
+	int c;
+
+        if (pthread_mutex_lock(&sound_mutex))
+	{
+		fatal("Cannot lock mutex");
+	}
+	while (!quited)
+	{
+                if (pthread_cond_wait(&sound_cond, &sound_mutex))
+		{
+			fatal("pthread_cond_wait failed");
+		}
+		if (!quited)
+		{
+			do {
+				c = updatesoundbuffer();
+			} while(c);
+		}
+	}
+        pthread_mutex_unlock(&sound_mutex);
+
+	return NULL;
+}
+
 void wakeupsoundthread()
 {
+    if (pthread_cond_signal(&sound_cond))
+    {
+        fatal("Couldn't signal vidc thread");
+    }
 }
 
+void closesoundthread()
+{
+	wakeupsoundthread();
+	pthread_join(sound_thread, NULL);
+}
+
+void startsoundthread(void)
+{
+    int r;
+    if (pthread_create(&sound_thread,NULL,_soundthread,NULL))
+    {
+        fatal("Couldn't create vidc thread");
+    }
+}
+
 static void domips(void)
 {
         mips=(float)inscount/1000000.0f;
@@ -70,8 +119,6 @@
 {
 }
 
-int quited=0;
-
 #ifdef VIDC_THREAD
 pthread_t thread;
 pthread_cond_t vidccond = PTHREAD_COND_INITIALIZER;
@@ -160,6 +207,7 @@
 
         install_int_ex(domips,MSEC_TO_TIMER(1000));
         install_int_ex(vblupdate,BPS_TO_TIMER(refresh));
+	startsoundthread();
         if (soundenabled) initsound();
         infocus=1;
         mousehackon=1;
Index: sound.c
===================================================================
--- sound.c	(revision 132)
+++ sound.c	(working copy)
@@ -7,38 +7,43 @@
 #include "mem.h"
 #include "iomd.h"
 
+int getbufferlen();
+
 int soundenabled;
-int soundbufferfull;
-int getbufferlen();
 uint32_t soundaddr[4];
 static int samplefreq;
 int soundinited,soundlatch,soundcount;
+static unsigned short bigsoundbuffer[8][44100<<1];
+static int bigsoundpos=0;
+static int bigsoundbufferhead=0; // sound buffer being written to
+static int bigsoundbuffertail=0; // sound buffer being read from
+static int oldsamplefreq=44100;
+static int soundon=0;
+static AUDIOSTREAM *as;
 
-AUDIOSTREAM *as;
 #define BUFFERLEN (4410>>1)
 //#define BUFFERLEN 11025
 
-int soundon=0;
-
 void initsound()
 {
         if (soundon)
         {
                 stop_audio_stream(as);
-                if (soundenabled) as=play_audio_stream(BUFFERLEN,16,1,44100,0,128);
-                else              as=play_audio_stream(BUFFERLEN,16,1,44100,255,128);
         }
-        install_sound(DIGI_AUTODETECT,MIDI_NONE,0);
-        if (soundenabled) as=play_audio_stream(BUFFERLEN,16,1,44100,0,128);
-        else              as=play_audio_stream(BUFFERLEN,16,1,44100,255,128);
-        samplefreq=44100;
-        soundon=1;
+        else
+        {
+                install_sound(DIGI_AUTODETECT,MIDI_NONE,0);
+                samplefreq=44100;
+                soundon=1;
+        }
+        if (soundenabled) as=play_audio_stream(BUFFERLEN,16,1,samplefreq,255,128);
+        else              as=play_audio_stream(BUFFERLEN,16,1,samplefreq,0,128);
 }
 
 void closesound()
 {
         stop_audio_stream(as);
-        as=play_audio_stream(BUFFERLEN,16,1,44100,0,128);
+        as=play_audio_stream(BUFFERLEN,16,1,samplefreq,0,128);
 //        remove_sound();
 }
 
@@ -50,19 +55,7 @@
         return end-start;
 }
 
-int bufferlen=100;
-unsigned short sndbuffer[16384];
-int sndsamples,sndpos=0,sndoffset=0;
 
-int soundinited;
-
-int soundcount=0,soundlatch;
-unsigned short bigsoundbuffer[8][44100<<1];
-int bigsoundbufferselect=0,bigsoundpos=0;
-int updatebigsound=0;
-
-int oldsamplefreq=44100;
-
 int getsamplefreq()
 {
         return samplefreq;
@@ -94,17 +87,25 @@
         voice_set_volume(as->voice,255);
 }
 
-int curbigsoundbuffer=0;
-
 void updatesoundirq()
 {
         uint32_t page,start,end,temp;
         int offset=(iomd.sndstat&1)<<1;
         int len;
         unsigned int c;
-        if (soundbufferfull && bigsoundbufferselect==curbigsoundbuffer)
+
+        if (!soundenabled)
         {
+                return;
+        }
+
+        // If bigsoundbufferhead is 1 less than bigsoundbuffertail, then
+        // the buffer list is full.
+        if (((bigsoundbufferhead+1)&7)==bigsoundbuffertail)
+        {
                 soundcount+=4000;
+                // kick the sound thread to clear the list
+                wakeupsoundthread();
                 return;
         }
         page=soundaddr[offset]&0xFFFFF000;
@@ -120,51 +121,54 @@
         for (c=start;c<end;c+=4)
         {
                 temp=ram[((c+page)&rammask)>>2];
-                bigsoundbuffer[bigsoundbufferselect][bigsoundpos++]=(temp&0xFFFF);//^0x8000;
-                bigsoundbuffer[bigsoundbufferselect][bigsoundpos++]=(temp>>16);//&0x8000;
+                bigsoundbuffer[bigsoundbufferhead][bigsoundpos++]=(temp&0xFFFF);//^0x8000;
+                bigsoundbuffer[bigsoundbufferhead][bigsoundpos++]=(temp>>16);//&0x8000;
                 if (bigsoundpos>=(BUFFERLEN<<1))
                 {
-//                        rpclog("Just finished buffer %i\n",bigsoundbufferselect);
-                        bigsoundbufferselect++;
-                        bigsoundbufferselect&=7;
+//                        rpclog("Just finished buffer %i\n",bigsoundbufferhead);
+                        bigsoundbufferhead++;
+                        bigsoundbufferhead&=7;
                         bigsoundpos=0;
-                        soundbufferfull++;
                         wakeupsoundthread();
                 }
         }
 //        fwrite(bigsoundbuffer,len<<2,1,sndfile);
 }
 
-FILE *sndfile;
+static FILE *sndfile;
 int updatesoundbuffer()
 {
         unsigned short *p;
         int c;
+	static int cnt = 0;
+
         if (!soundenabled)
         {
-                soundbufferfull=0;
                 return 0;
         }
 /*        if (!sndfile)
         {
                 sndfile=fopen("sound.pcm","wb");
         }*/
-        p=get_audio_stream_buffer(as);
-        while (!p) 
+        while (bigsoundbuffertail!=bigsoundbufferhead)
         {
-//                sleep(0);
                 p=get_audio_stream_buffer(as);
+                if (p)
+                {
+                        for (c=0;c<(BUFFERLEN<<1);c++)
+                                p[c]=bigsoundbuffer[bigsoundbuffertail][c]^0x8000;
+                        free_audio_stream_buffer(as);
+//                        rpclog("Writing buffer %i\n",bigsoundbuffertail);
+//                      fwrite(bigsoundbuffer[bigsoundbufferhead^1],BUFFERLEN<<2,1,sndfile);
+                        bigsoundbuffertail++;
+                        bigsoundbuffertail&=7;
+                }
+                else
+                {
+                        // No free audio buffer, try again later.
+                        break;
+                }
         }
-        soundbufferfull--;
-//        while (!p)
-//              p=get_audio_stream_buffer(as);
-        for (c=0;c<(BUFFERLEN<<1);c++)
-            p[c]=bigsoundbuffer[curbigsoundbuffer][c]^0x8000;
-        free_audio_stream_buffer(as);
-//        rpclog("Writing buffer %i\n",curbigsoundbuffer);
-        curbigsoundbuffer++;
-        curbigsoundbuffer&=7;
         return 0;
-//        fwrite(bigsoundbuffer[bigsoundbufferselect^1],BUFFERLEN<<2,1,sndfile);
 }
 
_______________________________________________
Rpcemu mailing list
[email protected]
http://www.riscos.info/cgi-bin/mailman/listinfo/rpcemu

Reply via email to