Sound in OSX working from Pearpc through ESD daemon

[ARCHIVED] About PearPC, a mostly obsolete PPC Mac emulator for Windows and Linux to run MacOS X 10.1 up to 10.4. Using QEMU is now recommended.

Moderators: Cat_7, Ronald P. Regensburg

zuc
Student Driver
Posts: 19
Joined: Wed Aug 18, 2004 1:59 pm

Post by zuc »

That's right. The Volume does not change when you move the Volume bar on the top.

What I encountered is that it's seems to be faster when the client OS is busy, loading somethning or so. When I did standart Window actions for exapmle maximizing minimizing or change the Focus from iTunes (used to play music) to some other programm and back, it was always followed by a small quality boost. Moving around the mouse in PearPc already helps. Sounds strange but that's the way it is.

During sound playback I always get this message in the PearPc console window:

[IO/rtl8139] <Warning> Bad package read by client? Active cd, CAPR ff24, CBA 0000, Tail 11, Head 11.

This message repeats as long as I play sound with a changing number after CAPR. I noticed the same error while surfing in the net but I never get bad files or bad data when I download in PearPc.
Has someone the same error? I have not tried the 3com driver. I don't know how to set it up.
User avatar
PPC_Digger
Forum All-Star
Posts: 1050
Joined: Thu Jul 22, 2004 9:02 am
Location: Israel

Post by PPC_Digger »

MacOSX wrote:
PPC_Digger wrote:
MacOSX wrote:I don't know if I'm being stupid or not but it seens that if you set the volume lower, it's smoother...or atleast after a while...

MacOSX
It is a little logical. Think about it that way: the lower the volume is, the smaller the sound amplitudes are, and the less work OSX has to do in order to play the sound. I think you're on to something.
I might be wrong because there are no volume level comtrol in OS X for the Network Driver....If you look in System Preferences, Sound, you'll see that the driver has no audio output controls...

MacOSX
Think about it this way: OSX does the processing after the sound is generated, so any change in the volume inside PearPC should change things a little bit. (I feel a little stupid trying to convice you that you're right)
MacOSX
Tinkerer
Posts: 52
Joined: Fri Jul 30, 2004 2:23 pm
Location: Canada

Post by MacOSX »

zuc wrote:That's right. The Volume does not change when you move the Volume bar on the top.

What I encountered is that it's seems to be faster when the client OS is busy, loading somethning or so. When I did standart Window actions for exapmle maximizing minimizing or change the Focus from iTunes (used to play music) to some other programm and back, it was always followed by a small quality boost. Moving around the mouse in PearPc already helps. Sounds strange but that's the way it is.

During sound playback I always get this message in the PearPc console window:

[IO/rtl8139] <Warning> Bad package read by client? Active cd, CAPR ff24, CBA 0000, Tail 11, Head 11.

This message repeats as long as I play sound with a changing number after CAPR. I noticed the same error while surfing in the net but I never get bad files or bad data when I download in PearPc.
Has someone the same error? I have not tried the 3com driver. I don't know how to set it up.
I tried the 3com driver but it didn't work for me...it just says the cable is disconnected in OS X

MacOSX
lord_muad_dib
Student Driver
Posts: 22
Joined: Sat May 15, 2004 2:47 pm
Location: italy

Post by lord_muad_dib »

PPC_Digger wrote:Does anyone remember this?
Too bad I didn't have any UNIX sound streaming expirience back then. (I still don't :lol: )
:lol:
i was sure on what i said 'cos i worked a lot with those things
unfortunely a flame started on it :(
it was so easy... and finally someone understood :mrgreen:

turnin' back on topic

when you switch between tasks it's a normal behavior that the sync changes a bit
due a poor multitasking management
when the priority of the process changes, windows gives more cpu cycles to all of the existing processes for a bit then returns back to normal
zuc
Student Driver
Posts: 19
Joined: Wed Aug 18, 2004 1:59 pm

Post by zuc »

But if giving more processor cycles makes the Sound less choppy, isn't there a way to tell Windows to give PearPc as much as CPU cycles as it needs for a fluid sound output manually?

I don't really know what a CPU cycle is. Does the amount of CPU cycles given to a programm relate to the CPU usage the Programm has? If so, how can then there be more CPU cycles given to PearPc if PPC already uses the whole Processor speed (minus the small speed the Host OS takes + some background programms?). Or am I completly wrong now and this has nothing to do with the speed of the CPU at all?. That'd explain why it's also choppy on fast PCs.
Sorry, I don't know much about hardware.
User avatar
PPC_Digger
Forum All-Star
Posts: 1050
Joined: Thu Jul 22, 2004 9:02 am
Location: Israel

Post by PPC_Digger »

zuc wrote:But if giving more processor cycles makes the Sound less choppy, isn't there a way to tell Windows to give PearPc as much as CPU cycles as it needs for a fluid sound output manually?

I don't really know what a CPU cycle is. Does the amount of CPU cycles given to a programm relate to the CPU usage the Programm has? If so, how can then there be more CPU cycles given to PearPc if PPC already uses the whole Processor speed (minus the small speed the Host OS takes + some background programms?). Or am I completly wrong now and this has nothing to do with the speed of the CPU at all?. That'd explain why it's also choppy on fast PCs.
Sorry, I don't know much about hardware.
Think of a CPU as a pipe of water. The faster your CPU is, the larger the pipe. All of the CPU time splits to smaller pipes (applications). The higher the application priority, the larger its pipe, and the more water (CPU cycles) it gets.
brimstone
Space Cadet
Posts: 1
Joined: Fri Jun 10, 2005 7:34 am

Post by brimstone »

PPC_Digger:
I followed your instructions to tweak the source, but I get 19 errors on Xcode2 on Tiger. A friend of mine gets 21 errors on Xcode2.1. We'd be happen to help you debug and get NetworkAudioDriver working under Tiger. Let me know if there's anyway we can help!
Starfury
Space Cadet
Posts: 1
Joined: Sat Jul 30, 2005 12:09 pm

Post by Starfury »

Hello everybody..

For a while I have used the NetworkAudioDevice driver successfully.

I found that the easiest way to compile it is running "make" and "make install" from the command line (as root). after restert (or "make load") there will be a Network Audio Device in the sound preference pane.

It is all working great, especially when the Esound server is on a different machine (I have a little Linux box with Esound next to my audio equipment; you can send the audio from both (or more) systems to it (there also is a esd driver for Win2000) ).

But in Tiger the Network Audio Device does not show up as a choice for sound output. When looking at /var/log/system.log I see a few lines telling me:

Code: Select all

Jul 30 13:13:53 localhost kernel [0]: Couldn't alloc class "org_samoconnor_driver_NetworkAudioDevice"
Jul 30 13:13:54 localhost kernel [0]: Couldn't alloc class "org_samoconnor_driver_NetworkAudioDevice"
Jul 30 13:13:57 localhost kernel [0]: Couldn't alloc class "org_samoconnor_driver_NetworkAudioDevice"
...
...
Jul 30 13:14:06 MacRoy kernel [0]: Couldn't alloc class "org_samoconnor_driver_NetworkAudioDevice"
Jul 30 13:14:9 MacRoy kernel [0]: Couldn't alloc class "org_samoconnor_driver_NetworkAudioDevice"
...
...
Jul 30 13:14:11 MacRoy kernel [0]: DMRantiClassic: releasing device for Mapper to use
Jul 30 13:14:11 MacRoy kernel [0]: DMRantiClassic: Mapper has claimed device
Jul 30 13:14:11 MacRoy kernel [0]: DMRantiClassic: re=claiming device after Mapper is done with it
I am not a coder and I don't really know what this is or even if these messages are related. But maybe someone here knows...

It would be great if it would work with Tiger.
Freiheit
Space Cadet
Posts: 1
Joined: Mon Aug 08, 2005 5:05 am

patch for tiger (warning: LOCKS OS X! also crappy...)

Post by Freiheit »

WARNING: This *will* lock up your machine after a while. Nice while it works, though... wish I knew more about Mac OS X kernel extensions.

Code: Select all

diff -ub --recursive NetworkAudioDevice.orig/Makefile NetworkAudioDevice/Makefile
--- NetworkAudioDevice.orig/Makefile	2003-06-10 16:06:26.000000000 -0700
+++ NetworkAudioDevice/Makefile	2005-08-07 14:07:10.000000000 -0700
@@ -1,8 +1,8 @@
-pbxbuild:
-	pbxbuild
+xcodebuild:
+	xcodebuild
 
 install:
-	pbxbuild install
+	xcodebuild install
 	rm -rf /System/Library/Extensions/NetworkAudioDriver.kext
 	mv /tmp/NetworkAudioDriver.dst/System/Library/Extensions/NetworkAudioDriver.kext \
         /System/Library/Extensions/
diff -ub --recursive NetworkAudioDevice.orig/NetworkAudioDriver.pbproj/project.pbxproj NetworkAudioDevice/NetworkAudioDriver.pbproj/project.pbxproj
--- NetworkAudioDevice.orig/NetworkAudioDriver.pbproj/project.pbxproj	2005-05-21 03:10:10.000000000 -0700
+++ NetworkAudioDevice/NetworkAudioDriver.pbproj/project.pbxproj	2005-08-07 20:00:37.000000000 -0700
@@ -270,6 +270,16 @@
 	<dict>
 		<key>com.apple.iokit.IOAudioFamily</key>
 		<string>1.1fc6</string>
+		<key>com.apple.kpi.bsd</key>
+		<string>8.0.0</string>
+		<key>com.apple.kpi.iokit</key>
+		<string>8.0.0</string>
+		<key>com.apple.kpi.libkern</key>
+		<string>8.0.0</string>
+		<key>com.apple.kpi.mach</key>
+		<string>8.0.0</string>
+		<key>com.apple.kpi.unsupported</key>
+		<string>8.0.0</string>
 	</dict>
 </dict>
 </plist>
diff -ub --recursive NetworkAudioDevice.orig/NetworkAudioEngine.cpp NetworkAudioDevice/NetworkAudioEngine.cpp
--- NetworkAudioDevice.orig/NetworkAudioEngine.cpp	2005-05-20 16:06:35.000000000 -0700
+++ NetworkAudioDevice/NetworkAudioEngine.cpp	2005-08-07 19:45:24.000000000 -0700
@@ -54,6 +54,8 @@
 #include <IOKit/pwr_mgt/RootDomain.h>
 
 extern "C" {
+#include <sys/kpi_socket.h>
+#include <sys/uio.h>
 #include <sys/socketvar.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -346,7 +348,6 @@
 void NetworkAudioEngine::tcpSendThread (void) {
     int error;
     struct iovec iovec[6];
-    struct uio uio;
     uint64_t connect_time = 0;
     uint64_t last_connect = 0;
     AbsoluteTime t;
@@ -361,39 +362,37 @@
     char name[ESD_NAME_LEN];
 
     strcpy (name, "mac");
-    uio.uio_procp = NULL;
-    uio.uio_segflg = UIO_SYSSPACE;
-    uio.uio_rw = UIO_WRITE;
 
     IOLog ("TCP Send thread started\n");
     IOLockLock(lock);
 
-    nanoseconds_to_absolutetime(NSEC_PER_BLOCK, &ticks_per_block);   
+    nanoseconds_to_absolutetime(NSEC_PER_BLOCK, (uint64_t *)&ticks_per_block);   
 
-    clock_get_uptime(&ticks);
+    clock_get_uptime((uint64_t *)&ticks);
 
     while (engine_running) {
-        thread_funnel_set (network_flock, TRUE);
+        //thread_funnel_set (network_flock, TRUE);
 
         // Try to connect to the server if needed
         if (sock == NULL) {
             IOLog ("Connecting to esound server...\n");
 
-            clock_get_uptime(&t);
-            absolutetime_to_nanoseconds(t, &connect_time);   
+            clock_get_uptime((uint64_t *)&t);
+            absolutetime_to_nanoseconds(*(uint64_t *)&t, &connect_time);   
 
             if (connect_time - last_connect > (uint64_t)2000000000) {
                 last_connect = connect_time;
 
-                error = socreate (AF_INET, &sock, SOCK_STREAM, IPPROTO_TCP);
+                //error = socreate (AF_INET, &sock, SOCK_STREAM, IPPROTO_TCP);
+                error = sock_socket (PF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, NULL, &sock);
                 if (error) {
-                    IOLog ("socreate failed!\n");
+                    IOLog ("sock_create failed!\n");
                 } else {
                     // Connect to the esound daemon
-                    error = soconnect (sock, (struct sockaddr*) &sockaddr);
+                    error = sock_connect (sock, (struct sockaddr*) &sockaddr, 0);
                     if (error) {
-                        IOLog ("socconnect returned %d\n", error);
-                        soclose (sock);
+                        IOLog ("sock_connect returned %d\n", error);
+                        sock_close (sock);
                         sock = NULL;
                     } else {
                         // Prepare an ESD header: key, endian, proto, format, rate, name
@@ -411,22 +410,33 @@
                         iovec[5].iov_base = (char*) name;
                         iovec[5].iov_len = ESD_NAME_LEN;
 
-                        uio.uio_iov = iovec;
-                        uio.uio_iovcnt = 6;
-                        uio.uio_offset = 0;
-                        uio.uio_resid = 0;
-                        for (int i = 0 ; i < uio.uio_iovcnt ; i++) {
-                            uio.uio_resid += iovec[i].iov_len;
+                        user_ssize_t restmp = 0;
+                        for (int i = 0 ; i < 6 ; i++) {
+                            restmp += iovec[i].iov_len;
                         }
 
                         // Wait for the socket to settle down after creation
-                        sbwait((sockbuf*)&(sock->so_snd));
+                        //sbwait((sockbuf*)&(sock->so_snd));
+
+                        struct msghdr msg[1];
+                        msg->msg_name = NULL;
+                        msg->msg_namelen = 0;
+                        msg->msg_iov = iovec;
+                        msg->msg_iovlen = 6;
+                        msg->msg_control = NULL;
+                        msg->msg_controllen = 0;
 
                         // Send the ESD header
-                        error = sosend (sock, NULL, &uio, NULL, NULL, 0);
-                        if (error) {
-                            IOLog ("sosend (header) returned %d\n", error);
-                            soclose (sock);
+                        //error = sosend (sock, NULL, uio, NULL, NULL, 0);
+                        size_t sentlen = 0;
+                        error = sock_send (sock, msg, 0, &sentlen);
+                        if (sentlen != restmp) {
+                            IOLog ("sock_send (header) wrote only %d of %d bytes\n", (int) sentlen, (int) restmp);
+                            sock_close (sock);
+                            sock = NULL;
+                        } else if (error) {
+                            IOLog ("sock_send (header) returned %d\n", error);
+                            sock_close (sock);
                             sock = NULL;
                         }
                     }
@@ -440,23 +450,34 @@
                 (char*) outputBuffer
                 + (currentBlock * BLOCK_BYTES);
             iovec[0].iov_len = BLOCK_BYTES;
-            uio.uio_iov = iovec;
-            uio.uio_resid = BLOCK_BYTES;
-            uio.uio_iovcnt = 1;
-            uio.uio_offset = 0;
 
-            error = sosend (sock, NULL, &uio, NULL, NULL, 0);
-            if (error) {
-                IOLog ("sosend (data) returned %d\n", error);
-                soshutdown (sock, 2);
-                soclose (sock);
+            struct msghdr msg[1];
+            msg->msg_name = NULL;
+            msg->msg_namelen = 0;
+            msg->msg_iov = iovec;
+            msg->msg_iovlen = 1;
+            msg->msg_control = NULL;
+            msg->msg_controllen = 0;
+
+            //error = sosend (sock, NULL, uio, NULL, NULL, 0);
+            size_t sentlen = 0;
+            error = sock_send (sock, msg, 0, &sentlen);
+            if (sentlen != BLOCK_BYTES) {
+                IOLog ("sock_send (data) wrote only %d of %d bytes\n", (int) sentlen, (int) BLOCK_BYTES);
+                sock_shutdown (sock, 2);
+                sock_close (sock);
+                sock = NULL;
+            } else if (error) {
+                IOLog ("sock_send (data) returned %d\n", error);
+                sock_shutdown (sock, 2);
+                sock_close (sock);
                 sock = NULL;
             }
         } else {
             IOLog ("no socket!\n");
         }
 
-        thread_funnel_set (network_flock, FALSE);
+        //thread_funnel_set (network_flock, FALSE);
 
         // Update the block count
         if (currentBlock == NUM_BLOCKS-1) {
@@ -469,17 +490,18 @@
 
         if  (engine_running) {
             // Go to sleep until the next block is ready.
-            ADD_ABSOLUTETIME(&ticks, &ticks_per_block);
-            assert_wait((event_t)&wait_timeout_event, THREAD_UNINT);
-            thread_set_timer_deadline (ticks);
+            *((uint64_t *)&ticks) += *((uint64_t *)&ticks_per_block);
+            //assert_wait((event_t)&wait_timeout_event, THREAD_UNINT);
+            //thread_set_timer_deadline (ticks);
+            assert_wait_deadline((event_t)&wait_timeout_event, THREAD_UNINT, *((uint64_t *)&ticks));
             thread_block(THREAD_CONTINUE_NULL);
         }
     }
     if  (disconnect) {
-        thread_funnel_set (network_flock, TRUE);
-        soshutdown (sock, 2);
-        soclose (sock);
-        thread_funnel_set (network_flock, FALSE);
+        //thread_funnel_set (network_flock, TRUE);
+        sock_shutdown (sock, 2);
+        sock_close (sock);
+        //thread_funnel_set (network_flock, FALSE);
         sock = NULL;
     }
     IOLog ("TCP Send thread exiting...\n");
diff -ub --recursive NetworkAudioDevice.orig/NetworkAudioEngine.h NetworkAudioDevice/NetworkAudioEngine.h
--- NetworkAudioDevice.orig/NetworkAudioEngine.h	2003-06-15 05:24:06.000000000 -0700
+++ NetworkAudioDevice/NetworkAudioEngine.h	2005-08-07 18:01:24.000000000 -0700
@@ -45,6 +45,7 @@
 
 #include <IOKit/audio/IOAudioEngine.h>
 extern "C" {
+#include <sys/kpi_socket.h>
 #include <sys/socketvar.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -78,7 +79,7 @@
     UInt32 engine_running;
     
     IOLock* lock;
-    struct socket* sock;
+    socket_t sock;
     struct sockaddr_in sockaddr;
 
     virtual bool init();
Locked