Re: coreaudio-api digest, Vol 1 #146 - 10 msgs
Re: coreaudio-api digest, Vol 1 #146 - 10 msgs
- Subject: Re: coreaudio-api digest, Vol 1 #146 - 10 msgs
- From: "David A. Gatwood" <email@hidden>
- Date: Mon, 3 Dec 2001 18:06:37 -0800 (PST)
On Mon, 3 Dec 2001, David A. Gatwood wrote:
>
On Mon, 3 Dec 2001, Bill Stewart wrote:
>
>
> It might be interesting to post these to the list.
>
>
>
> We worked out a scheme for these values ourselves in 10.1 and it would be
>
> interesting to see how you've worked this.
>
>
What I have so far is just a first revision. I came up with a best guess
>
based on percentage of CPU cycles the relevant thread used when working
>
correctly, multiplied that percentage into bus cycles, added a little
>
padding, and went with it. It's a good approximation for machines with
>
a 133 MHz system bus. It also works quite well at 100 MHz, largely by
>
accident and a little buffering.
>
>
Before I post the code, I'd like to try to get the bus speed and do the
>
math correctly on a per-machine basis, but I'm having problems with
>
sysctlbyname. I need to go bug some engineers over in the next building,
>
and I'll get back to you. :-)
Didn't need to beat on any heads. Found the issue in the sysctl utility's
source code. Turns out the new-style sysctlbyname doesn't work with many
of the built-ins, which still use the old-style mechanism for registering
the sysctl. Oh well, easy enough to work around.
Some comments on the patches. To build mpg123 against esound, you need to
tweak the makefile slightly. Look under option linux-ppc-esd and take out
the -mcpu=ppc. Then, look up at the AUDIO_LIB line right above that, and
add -L/sw/lib (assuming you installed esound using fink, else specify
paths as appropriate). Then make with "make linux-ppc-esd". Yes, it's
gross, but I haven't found any other way to link against esound.
Next comment... I was wrong about the bus speed. The patches were against
a 100 MHz bus speed. I've updated the ones for mpg123, but not for
esound. For your convenience, I have included the original hard-coded
values in the mpg123 sources. The new values for esound should be approx.
ttcpolicy.computation=(getbusspeed() / 2520);
ttcpolicy.constraint=(getbusspeed() / 1680);
or thereabouts, with the same period.
Finally, these were diffs against a slightly patched version of both
mpg123 and esound that I use in my own pet project, SongCue (which runs on
OS X -- check out
http://www.songcue.com). You may get some easily
corrected glitches when patching against an unmodified tree. Apologies in
advance.
Later,
David
---------------------- begin mpg123 patch ----------------------
Common subdirectories: mpg123-0.59r/jukebox and
mpg123-0.59r-patched/jukebox
diff -u mpg123-0.59r/mpg123.c mpg123-0.59r-patched/mpg123.c
--- mpg123-0.59r/mpg123.c Mon Dec 3 17:34:18 2001
+++ mpg123-0.59r-patched/mpg123.c Mon Dec 3 17:33:48 2001
@@ -18,13 +18,19 @@
#include <string.h>
#include <fcntl.h>
-#if 0
+#if 1
#define SET_RT
#endif
#ifdef SET_RT
#include <sched.h>
+#if (defined(__ppc__) && defined(__APPLE__))
+#include <mach/mach_init.h>
+#include <mach/task_policy.h>
+#include <mach/thread_act.h>
+#include <mach/thread_policy.h>
+#endif
#endif
#include "mpg123.h"
@@ -105,6 +111,12 @@
void set_synth_functions(struct frame *fr);
+#ifdef SET_RT
+#if (defined(__ppc__) && defined(__APPLE__))
+int getbusspeed();
+#endif
+#endif
+
char *handle_remote(void)
{
switch(frontend_type) {
@@ -884,15 +896,38 @@
#endif
#ifdef SET_RT
- if (param.realtime) { /* Get real-time priority */
+ if (param.realtime) { /* Get real-time priority */
+#if (defined(__ppc__) && defined(__APPLE__))
+ struct thread_time_constraint_policy ttcpolicy;
+ fprintf(stderr,"Getting real-time priority\n");
+
+ /* This is in AbsoluteTime units, which are equal to
+ 1/4 the bus speed on most machines. */
+
+ // hard-coded numbers are approximations for 100 MHz bus speed.
+ // assume that app deals in frame-sized chunks, e.g. 30 per second.
+ // ttcpolicy.period=833333;
+ ttcpolicy.period=(getbusspeed() / 120);
+ // ttcpolicy.computation=60000;
+ ttcpolicy.computation=(getbusspeed() / 1440)
+ // ttcpolicy.constraint=120000;
+ ttcpolicy.constraint=(getbusspeed() / 720)
+ ttcpolicy.preemptible=1;
+
+ if (thread_policy_set(mach_thread_self(),
+ THREAD_TIME_CONSTRAINT_POLICY, (int *)&ttcpolicy,
+ THREAD_TIME_CONSTRAINT_POLICY_COUNT) != KERN_SUCCESS)
+ fprintf(stderr, "Can't do thread_policy_set\n");
+#else /* POSIX_RT */
struct sched_param sp;
fprintf(stderr,"Getting real-time priority\n");
memset(&sp, 0, sizeof(struct sched_param));
sp.sched_priority = sched_get_priority_min(SCHED_FIFO);
- if (sched_setscheduler(0, SCHED_RR, &sp) == -1)
+ if (pthread_setschedpolicy(0, SCHED_RR, &sp) == -1)
fprintf(stderr,"Can't get real-time priority\n");
- }
-#endif
+#endif /* MACH_RT */
+ }
+#endif /* SET_RT */
set_synth_functions(&fr);
@@ -1216,4 +1251,29 @@
usr2flag = TRUE;
int2flag = TRUE;
}
+
+#ifdef SET_RT
+#if (defined(__ppc__) && defined(__APPLE__))
+int get_bus_speed()
+{
+int mib[2];
+unsigned int miblen;
+int busspeed;
+int retval;
+size_t len;
+
+mib[0]=CTL_HW;
+mib[1]=HW_BUS_FREQ;
+miblen=2;
+len=4;
+retval = sysctl(mib, miblen, &busspeed, &len, NULL, 0);
+
+/* Note: you should really check retval here, see man sysctl for info */
+
+// printf("%d\n", busspeed);
+return busspeed;
+}
+
+#endif
+#endif
---------------------- end mpg123 patch ----------------------
---------------------- begin esound patch ----------------------
diff -ru esound-0.2.22/esd.c esound-0.2.22-patched/esd.c
--- esound-0.2.22/esd.c Mon Sep 24 20:45:05 2001
+++ esound-0.2.22-patched/esd.c Mon Sep 24 20:50:05 2001
@@ -13,6 +13,28 @@
#include <unistd.h>
#endif
+#if (defined(__ppc__) && defined(__APPLE__))
+#define MACH_RT
+#endif
+
+#ifndef MACH_RT
+#if (defined(SCHED_FIFO) || defined(SCHED_RR))
+#define POSIX_RT
+#endif
+#endif
+
+#ifdef POSIX_RT
+#include <pthread.h>
+#else
+#ifdef MACH_RT
+#include <mach/mach_init.h>
+#include <mach/task_policy.h>
+#include <mach/thread_act.h>
+#include <mach/thread_policy.h>
+#include <sched.h>
+#endif
+#endif
+
/*******************************************************************/
/* esd.c - prototypes */
void set_audio_buffer( void *buf, esd_format_t format, int magl, int
magr,
@@ -476,6 +498,15 @@
int itmp;
void *output_buffer = NULL;
+#ifdef POSIX_RT
+ struct sched_param sp;
+#else
+#ifdef MACH_RT
+ struct thread_time_constraint_policy ttcpolicy;
+ // struct task_category_policy tcatpolicy;
+#endif
+#endif
+ int ret;
/* begin test scaffolding parameters */
/* int format = AFMT_U8; AFMT_S16_LE; */
@@ -488,6 +519,33 @@
int default_format = ESD_BITS16 | ESD_STEREO;
/* end test scaffolding parameters */
+
+#ifdef POSIX_RT
+ fprintf(stderr,"Getting real-time priority\n");
+ memset(&sp, 0, sizeof(struct sched_param));
+#ifdef SCHED_FIFO
+#define MYSCHED SCHED_FIFO
+#else
+#define MYSCHED SCHED_RR
+#endif
+ sp.sched_priority = sched_get_priority_min(MYSCHED);
+ // sp.sched_priority = 96;
+ if (pthread_setschedparam(pthread_self(), MYSCHED, &sp))
+ fprintf(stderr,"Can't get real-time priority\n");
+#else
+#ifdef MACH_RT
+ ttcpolicy.period=833333;
+ ttcpolicy.computation=40000;
+ ttcpolicy.constraint=60000;
+ ttcpolicy.preemptible=1;
+
+ if ((ret=thread_policy_set(mach_thread_self(),
+ THREAD_TIME_CONSTRAINT_POLICY, (int *)&ttcpolicy,
+ THREAD_TIME_CONSTRAINT_POLICY_COUNT)) != KERN_SUCCESS)
+ fprintf(stderr, "Can't do thread_policy_set: %d\n", ret);
+#endif
+#endif
+
/* parse the command line args */
for ( arg = 1 ; arg < argc ; arg++ ) {
---------------------- end esound patch ----------------------
---------------------------------------------------------------------
Check out my weekly web comic:
http://www.techmagazine.org