Apostolos\’ Daily Plate

Μητέρες ανηλίκων!

Posted in «Αθλητισμός» by asyropoulos on Φεβρουαρίου 15, 2015

Δεν θεωρώ πως οι εργαζόμενοι πρέπει να βγαίνουν στη σύνταξη στα 67 αλλά θεωρώ πως όλοι πρέπει να βγαίνουν στη σύνατξη στα 60 ετός βέβαια από αυτούς που αποδεδειγμένα εργάζονται σε αντίξοες συνθήκες, όπως ορυχεία κ.λπ. Όμως πάντα θεωρούσα παράλογο αυτό που συμβαίνει στη Δημόσιο της  χώρα μας όπου μητέρες με ανήλικα 16 και 17 ετών βγαίνουν στη σύνταξη ως μητρέρες ανηλίκων! Πολύ απλά είναι τεράστια αδικία για εργαζόμενες που κάναν παιδιά μικρές και φυσικά δεν τους  «πιάνει» το μέτρο. Από την άλλη είναι ένα μέτρο με ηλίθιο σκεπτικό επειδή αν μια εργαζόμενη έχει ανήλικο παιδί πρέπει το κράτος να φροντίζει για παιδικούς σταθμούς και νηπιαγωγεία και όχι να δίνει σύνταξη σε εργαζόμενες 40 και 45 ετών! Δυστυχώς, τέτοιες «στρεβλώσεις» βλέπουν οι διάφοροι καλοθελητές και μας χαρακτηρίζουν ως έθνος τεμπέλιδων.

Advertisements

Compiling pulseaudio-5.99.3 on Solaris x86

Posted in Πληροφορική, OpenIndiana, OpenSolaris by asyropoulos on Φεβρουαρίου 9, 2015

Oracle has released some patches that can be used to compile a very old version of PulseAudio. I have used these patches and after adding some things and removing some others I have successfully managed to compile Pulse Audio. The patches follows:


diff -rupN pulseaudio-5.99.3.old/src/daemon/default.pa.in pulseaudio-5.99.3/src/daemon/default.pa.in
--- pulseaudio-5.99.3.old/src/daemon/default.pa.in 2015-01-21 16:16:53.000000000 +0200
+++ pulseaudio-5.99.3/src/daemon/default.pa.in 2015-02-08 22:11:11.577334805 +0200
@@ -54,7 +54,7 @@ ifelse(@HAVE_ALSA@, 1, [dnl
#load-module module-alsa-source device=hw:1,0
])dnl
ifelse(@HAVE_OSS_OUTPUT@, 1, [dnl
-#load-module module-oss device="/dev/dsp" sink_name=output source_name=input
+load-module module-oss device="/dev/dsp" sink_name=output source_name=input
#load-module module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
])dnl
ifelse(@HAVE_WAVEOUT@, 1, [dnl
diff -rupN pulseaudio-5.99.3.old/src/daemon/esdcompat.in pulseaudio-5.99.3/src/daemon/esdcompat.in
--- pulseaudio-5.99.3.old/src/daemon/esdcompat.in 2015-01-21 16:16:53.000000000 +0200
+++ pulseaudio-5.99.3/src/daemon/esdcompat.in 2015-02-08 22:11:11.577649151 +0200
@@ -88,7 +88,10 @@ EOF
;;
esac

– shift
+ # don’t try to shift nonexisting args
+ if [ $1 ]; then
+ shift
+ fi
done

eval «exec ‘@PA_BINARY@’$ARGS»
diff -rupN pulseaudio-5.99.3.old/src/modules/gconf/module-gconf.c pulseaudio-5.99.3/src/modules/gconf/module-gconf.c
— pulseaudio-5.99.3.old/src/modules/gconf/module-gconf.c 2015-01-21 16:16:53.000000000 +0200
+++ pulseaudio-5.99.3/src/modules/gconf/module-gconf.c 2015-02-08 22:11:11.578283648 +0200
@@ -56,7 +56,7 @@ struct module_item {
uint32_t index;
};

-struct module_info {
+struct pa_module_info {
struct userdata *userdata;
char *name;

@@ -129,7 +129,7 @@ static char *read_string(struct userdata
}
}

-static void unload_one_module(struct module_info *m, unsigned i) {
+static void unload_one_module(struct pa_module_info *m, unsigned i) {
struct userdata *u;

pa_assert(m);
@@ -148,7 +148,7 @@ static void unload_one_module(struct mod
m->items[i].name = m->items[i].args = NULL;
}

-static void unload_all_modules(struct module_info *m) {
+static void unload_all_modules(struct pa_module_info *m) {
unsigned i;

pa_assert(m);
@@ -160,7 +160,7 @@ static void unload_all_modules(struct mo
}

static void load_module(
– struct module_info *m,
+ struct pa_module_info *m,
unsigned i,
const char *name,
const char *args,
@@ -199,7 +199,7 @@ static void load_module(
}

static void module_info_free(void *p) {
– struct module_info *m = p;
+ struct pa_module_info *m = p;

pa_assert(m);

@@ -227,14 +227,14 @@ static int handle_event(struct userdata

case ‘+’: {
char *name;
– struct module_info *m;
+ struct pa_module_info *m;
unsigned i, j;

if (!(name = read_string(u)))
goto fail;

if (!(m = pa_hashmap_get(u->module_infos, name))) {
– m = pa_xnew(struct module_info, 1);
+ m = pa_xnew(struct pa_module_info, 1);
m->userdata = u;
m->name = name;
m->n_items = 0;
diff -rupN pulseaudio-5.99.3.old/src/modules/module-augment-properties.c pulseaudio-5.99.3/src/modules/module-augment-properties.c
— pulseaudio-5.99.3.old/src/modules/module-augment-properties.c 2015-01-21 16:16:53.000000000 +0200
+++ pulseaudio-5.99.3/src/modules/module-augment-properties.c 2015-02-08 22:11:11.578666761 +0200
@@ -158,8 +158,8 @@ static void update_rule(struct rule *r)
/* Let’s try a more aggressive search, but only one level */
if ((desktopfiles_dir = opendir(DESKTOPFILEDIR))) {
while ((dir = readdir(desktopfiles_dir))) {
– if (dir->d_type != DT_DIR
– || pa_streq(dir->d_name, «.»)
+ if (/* dir->d_type != DT_DIR
+ || */ pa_streq(dir->d_name, «.»)
|| pa_streq(dir->d_name, «..»))
continue;

diff -rupN pulseaudio-5.99.3.old/src/modules/module-solaris.c pulseaudio-5.99.3/src/modules/module-solaris.c
— pulseaudio-5.99.3.old/src/modules/module-solaris.c 2015-01-21 16:16:53.000000000 +0200
+++ pulseaudio-5.99.3/src/modules/module-solaris.c 2015-02-08 22:11:11.579626929 +0200
@@ -135,6 +135,7 @@ static const char* const valid_modargs[]
static uint64_t get_playback_buffered_bytes(struct userdata *u) {
audio_info_t info;
uint64_t played_bytes;
+ int64_t buffered_bytes;
int err;

pa_assert(u->sink);
@@ -161,10 +162,13 @@ static uint64_t get_playback_buffered_by

pa_smoother_put(u->smoother, pa_rtclock_now(), pa_bytes_to_usec(played_bytes, &u->sink->sample_spec));

– if (u->written_bytes > played_bytes)
– return u->written_bytes – played_bytes;
– else
– return 0;
+ buffered_bytes = u->written_bytes – played_bytes;
+
+ if (buffered_bytes < 0) {
+ buffered_bytes = 0;
+ }
+
+ return (uint64_t) buffered_bytes;
}

static pa_usec_t sink_get_latency(struct userdata *u, pa_sample_spec *ss) {
@@ -415,7 +419,7 @@ static int sink_process_msg(pa_msgobject
if (unsuspend(u) < 0) return -1; u->sink->get_volume(u->sink);
– u->sink->get_mute(u->sink);
+ u->sink->get_mute(u->sink,(_Bool*)1);
}
u->sink_suspended = false;
}
@@ -486,14 +490,26 @@ static int source_process_msg(pa_msgobje
static void sink_set_volume(pa_sink *s) {
struct userdata *u;
audio_info_t info;
+ pa_volume_t v;

pa_assert_se(u = s->userdata);

+ if (u->fd < 0) { + u->fd = pa_open_cloexec(u->device_name, u->mode | O_NONBLOCK, 0);
+ }
+
if (u->fd >= 0) {
AUDIO_INITINFO(&info);

– info.play.gain = pa_cvolume_max(&s->real_volume) * AUDIO_MAX_GAIN / PA_VOLUME_NORM;
– pa_assert(info.play.gain <= AUDIO_MAX_GAIN); + v = pa_cvolume_max(&s->real_volume);
+ if (v > PA_VOLUME_NORM) {
+ v = PA_VOLUME_NORM;
+ }
+
+ info.play.gain = v * AUDIO_MAX_GAIN / PA_VOLUME_NORM;
+
+ pa_log_debug(«PA_VOLUME_NORM is %ld», PA_VOLUME_NORM);
+ pa_log_debug(«Setting volume %ld %ld», v, info.play.gain);

if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) { if (errno == EINVAL) @@ -513,22 +529,29 @@ static void sink_get_volume(pa_sink *s) if (u->fd >= 0) {
if (ioctl(u->fd, AUDIO_GETINFO, &info) < 0) pa_log(«AUDIO_SETINFO: %s», pa_cstrerror(errno)); – else + else { + pa_log_debug(«Getting volume %ld %ld», info.play.gain, (info.play.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN)); pa_cvolume_set(&s->real_volume, s->sample_spec.channels, info.play.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN);
+ }
}
}

static void source_set_volume(pa_source *s) {
struct userdata *u;
audio_info_t info;
+ pa_volume_t v;

pa_assert_se(u = s->userdata);

if (u->fd >= 0) {
AUDIO_INITINFO(&info);

– info.play.gain = pa_cvolume_max(&s->real_volume) * AUDIO_MAX_GAIN / PA_VOLUME_NORM;
– pa_assert(info.play.gain <= AUDIO_MAX_GAIN); + v = pa_cvolume_max(&s->real_volume);
+ if (v > PA_VOLUME_NORM) {
+ v = PA_VOLUME_NORM;
+ }
+
+ info.play.gain = v * AUDIO_MAX_GAIN / PA_VOLUME_NORM;

if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) { if (errno == EINVAL) @@ -1034,7 +1057,7 @@ int pa__init(pa_module *m) { if (sink_new_data.muted_is_set) u->sink->set_mute(u->sink);
else
– u->sink->get_mute(u->sink);
+ u->sink->get_mute(u->sink,(_Bool*)1);

pa_sink_put(u->sink);
}
diff -rupN pulseaudio-5.99.3.old/src/modules/oss/module-oss.c pulseaudio-5.99.3/src/modules/oss/module-oss.c
— pulseaudio-5.99.3.old/src/modules/oss/module-oss.c 2015-01-21 16:16:53.000000000 +0200
+++ pulseaudio-5.99.3/src/modules/oss/module-oss.c 2015-02-08 22:11:11.581263125 +0200
@@ -32,6 +32,10 @@
*
*/

+#define HAVE_OSSV4
+#define TRUE 1
+#define FALSE 0
+
#ifdef HAVE_CONFIG_H
#include
#endif
@@ -123,7 +127,18 @@ struct userdata {
int mode;

int mixer_fd;
+
+#ifdef HAVE_OSSV4
+ int mixer_dev;
+ int mixer_sink_control;
+ int mixer_source_control;
+ int mixer_cmax;
+ int mixer_dsp_fd;
+ oss_mixext sink_mixext;
+ oss_mixext source_mixext;
+#else
int mixer_devmask;
+#endif

int nfrags, frag_size, orig_frag_size;

@@ -809,6 +824,160 @@ static int source_process_msg(pa_msgobje
return ret;
}

+#ifdef HAVE_OSSV4
+
+static const char *
+mixer_ext_type_get_name (int type)
+{
+ switch (type) {
+ case MIXT_DEVROOT:
+ return «Device root entry»;
+ case MIXT_GROUP:
+ return «Controller group»;
+ case MIXT_ONOFF:
+ return «On/Off switch»;
+ case MIXT_ENUM:
+ return «Enumeration control»;
+ case MIXT_MONOSLIDER:
+ return «Mono slider (0-255)»;
+ case MIXT_STEREOSLIDER:
+ return «Stereo slider (0-255)»;
+ case MIXT_MESSAGE:
+ return «Textual message»;
+ case MIXT_MONOVU:
+ return «Mono VU meter value»;
+ case MIXT_STEREOVU:
+ return «Stereo VU meter value»;
+ case MIXT_MONOPEAK:
+ return «Mono VU meter peak value»;
+ case MIXT_STEREOPEAK:
+ return «Stereo VU meter peak value»;
+ case MIXT_RADIOGROUP:
+ return «Radio button group»;
+ case MIXT_MARKER:
+ /* Separator between normal and extension entries */
+ return «Separator»;
+ case MIXT_VALUE:
+ return «Decimal value entry»;
+ case MIXT_HEXVALUE:
+ return «Hex value entry»;
+ case MIXT_SLIDER:
+ return «Mono slider (31-bit value range)»;
+ case MIXT_3D:
+ return «3D»;
+ case MIXT_MONOSLIDER16:
+ return «Mono slider (0-32767)»;
+ case MIXT_STEREOSLIDER16:
+ return «Stereo slider (0-32767)»;
+ case MIXT_MUTE:
+ return «Mute switch»;
+ default:
+ break;
+ }
+
+ return «Unknown»;
+}
+
+void
+mixer_showflags (int flags)
+{
+ struct
+ {
+ int flag;
+ char nick[16];
+ } all_flags[] = {
+ /* first the important ones */
+ {
+ MIXF_MAINVOL, «MAINVOL»}, {
+ MIXF_PCMVOL, «PCMVOL»}, {
+ MIXF_RECVOL, «RECVOL»}, {
+ MIXF_MONVOL, «MONVOL»}, {
+ MIXF_DESCR, «DESCR»},
+
+ /* now the rest in the right order */
+ {
+ MIXF_READABLE, «READABLE»}, {
+ MIXF_WRITEABLE, «WRITABLE»}, {
+ MIXF_POLL, «POLL»}, {
+ MIXF_HZ, «HZ»}, {
+ MIXF_STRING, «STRING»}, {
+ MIXF_DYNAMIC, «DYNAMIC»}, {
+ MIXF_OKFAIL, «OKFAIL»}, {
+ MIXF_FLAT, «FLAT»}, {
+ MIXF_LEGACY, «LEGACY»}, {
+ MIXF_CENTIBEL, «CENTIBEL»}, {
+ MIXF_DECIBEL, «DECIBEL»}, {
+ MIXF_WIDE, «WIDE»}
+ };
+ int num_flags = (sizeof (all_flags) / sizeof ((all_flags)[0]));
+ int i;
+
+ if (flags == 0) {
+ pa_log_debug (» flags : None»);
+ return;
+ }
+
+ for (i=0; i < num_flags; i++) { + if ((flags & all_flags[i].flag)) { + pa_log_debug (» flag : %s», all_flags[i].nick); + flags &= ~all_flags[i].flag; /* unset */ + } + } + + /* Unknown flags? */ + if (flags != 0) { + pa_log_debug (» flag : ????»); + } + + return; +} + +static void sink_get_volume(pa_sink *s) { + struct userdata *u; + + pa_assert_se(u = s->userdata);
+
+ if (pa_oss_get_volume(u->mixer_dsp_fd, &(u->sink_mixext), &s->sample_spec, &s->real_volume) >= 0)
+ return;
+
+ pa_log_info(«Device doesn’t support reading mixer settings: %s», pa_cstrerror(errno));
+}
+
+static void sink_set_volume(pa_sink *s) {
+ struct userdata *u;
+
+ pa_assert_se(u = s->userdata);
+
+ if (pa_oss_set_volume(u->mixer_dsp_fd, &(u->sink_mixext), &s->sample_spec, &s->real_volume) >= 0)
+ return;
+
+ pa_log_info(«Device doesn’t support writing mixer settings: %s», pa_cstrerror(errno));
+}
+
+static void source_get_volume(pa_source *s) {
+ struct userdata *u;
+
+ pa_assert_se(u = s->userdata);
+
+ if (pa_oss_get_volume(u->mixer_dsp_fd, &(u->source_mixext), &s->sample_spec, &s->real_volume) >= 0)
+ return;
+
+ pa_log_info(«Device doesn’t support reading mixer settings: %s», pa_cstrerror(errno));
+}
+
+static void source_set_volume(pa_source *s) {
+ struct userdata *u;
+
+ pa_assert_se(u = s->userdata);
+
+ if (pa_oss_set_volume(u->mixer_dsp_fd, &(u->source_mixext), &s->sample_spec, &s->real_volume) >= 0)
+ return;
+
+ pa_log_info(«Device doesn’t support writing mixer settings: %s», pa_cstrerror(errno));
+}
+
+#else
+
static void sink_get_volume(pa_sink *s) {
struct userdata *u;

@@ -880,6 +1049,7 @@ static void source_set_volume(pa_source

pa_log_info(«Device doesn’t support writing mixer settings: %s», pa_cstrerror(errno));
}
+#endif

static void thread_func(void *userdata) {
struct userdata *u = userdata;
@@ -1162,6 +1332,11 @@ finish:

int pa__init(pa_module*m) {

+#ifdef HAVE_OSSV4
+ struct oss_sysinfo si = { {0,}, };
+ struct oss_mixerinfo mi = { 0, };
+#endif
+
struct audio_buf_info info;
struct userdata *u = NULL;
const char *dev;
@@ -1259,7 +1434,9 @@ int pa__init(pa_module*m) {
m->userdata = u;
u->fd = fd;
u->mixer_fd = -1;
+#ifndef HAVE_OSSV4
u->mixer_devmask = 0;
+#endif
u->use_getospace = u->use_getispace = true;
u->use_getodelay = true;
u->mode = mode;
@@ -1426,6 +1603,194 @@ int pa__init(pa_module*m) {
if ((u->mixer_fd = pa_oss_open_mixer_for_device(u->device_name)) >= 0) {
bool do_close = true;

+#ifdef HAVE_OSSV4
+#define IGNORE_DEV 1
+ int i;
+
+ u->mixer_dsp_fd = -1;
+
+ if (ioctl (u->mixer_fd, SNDCTL_SYSINFO, &si) < 0) {
+ pa_log_debug («SNDCTL_SYSINFO failed»);
+ goto fail;
+ }
+ for (i = 0; i < si.nummixers; i++) { + mi.dev = i; + if (ioctl (u->mixer_fd, SNDCTL_MIXERINFO, &mi) < 0) {
+ pa_log_debug(«SNDCTL_MIXERINFO failed»);
+ goto fail;
+ }
+ if (mi.enabled != 0) {
+ /*
+ * There could be multiple mixers. First we only care about
+ * ones which are enabled. In any case we should not touch
+ * disabled mixers! But beyond that it may not be clear which
+ * one to use! There is a way to relate the card number to the
+ * device node name. But there does not seem to be a real good
+ * way to chose which one to use. So maybe an env. var. could
+ * be used to select a dsp device node name and then pick the
+ * correct mixer number. (See load_devices() in audioctl).
+ * This code now will always pick the first enabled mixer
+ * found. Which may be wrong for multiple mixers and/or sound
+ * cards. It may be possible/desirable to control all mixers
+ * found at the same time???
+ */
+ break;
+ }
+ }
+
+ if (i < si.nummixers) {
+ struct stat sbuf;
+
+ if ((stat(mi.devnode, &sbuf) != 0) ||
+ ((sbuf.st_mode & S_IFCHR) == 0)) {
+ pa_log(«Failed to get mixer dsp device.»);
+ i = si.nummixers;
+ }
+ }
+
+ if (i < si.nummixers && + (u->mixer_dsp_fd = pa_oss_open_mixer(mi.devnode)) >= 0) {
+
+ /* Will cause for loop to exit if not filled in by OSS */
+ u->mixer_cmax = -1;
+ if (ioctl(u->mixer_dsp_fd, SNDCTL_MIX_NREXT, &u->mixer_cmax) < 0) { + pa_log(«Failed to get max control.»); + goto fail; + } + + pa_log_debug («Opened mixer device %d with %d controls\n», + mi.dev, mi.nrext); + + u->mixer_sink_control = -1;
+ u->mixer_source_control = -1;
+
+ for (i=0; i < u->mixer_cmax; i++) {
+ memset (&(u->sink_mixext), 0, sizeof (oss_mixext));
+
+#ifdef IGNORE_DEV
+ /* This will cause dev to be ignored */
+ u->sink_mixext.dev = -1;
+#else
+ u->sink_mixext.dev = mi.dev;
+#endif
+
+ /*
+ * The real way to pick a control on a mixer is with this
+ * number. Note that control numbers are unique across all
+ * mixers. So dev can just be ignored. When dev is included
+ * it will only be used to check for correct dev from
+ * userland. But it will not be used to select a mixer.
+ */
+ u->sink_mixext.ctrl = i;
+
+ pa_log_debug («Control %d», u->sink_mixext.ctrl);
+
+ if (ioctl (u->mixer_dsp_fd, SNDCTL_MIX_EXTINFO,
+ &(u->sink_mixext)) < 0) { + pa_log_debug («SNDCTL_MIX_EXTINFO failed»); + continue; + } + + pa_log_debug (» name : %s», u->sink_mixext.extname);
+ pa_log_debug (» type : %s (%d)»,
+ mixer_ext_type_get_name (u->sink_mixext.type),
+ u->sink_mixext.type);
+ pa_log_debug (» maxval : %d», u->sink_mixext.maxvalue);
+ pa_log_debug (» parent : %d», u->sink_mixext.parent);
+ mixer_showflags (u->sink_mixext.flags);
+
+ if ((u->sink_mixext.flags & MIXF_PCMVOL)) {
+ pa_log_debug («First PCM control: %d», i);
+ u->mixer_sink_control = i;
+ break;
+ }
+
+ /*
+ * Note that MIXF_MAINVOL may not be an exclusive single
+ * control. For example on AudioHD there will be one for each
+ * output jack (Green, Black, Orange…). So to really do a
+ * master volume you would need to do all MIXF_MAINVOL at the
+ * same time…
+ */
+ if (((u->sink_mixext.flags & MIXF_MAINVOL)) &&
+ u->mixer_sink_control == -1) {
+ pa_log_debug («First main volume control: %d», i);
+ u->mixer_sink_control = i;
+ }
+ }
+
+ if (u->mixer_sink_control != -1) {
+ pa_log_debug («Setting OSS sink callbacks.»);
+ pa_sink_set_get_volume_callback(u->sink, sink_get_volume);
+ pa_sink_set_set_volume_callback(u->sink, sink_set_volume);
+ u->sink->n_volume_steps = 101;
+ do_close = FALSE;
+ } else {
+ pa_log_debug («Not setting OSS sink callbacks.»);
+ }
+
+ for (i=0; i < mi.nrext; i++) { + memset (&(u->source_mixext), 0, sizeof (oss_mixext));
+#ifdef IGNORE_DEV
+ /* This will cause dev to be ignored */
+ u->source_mixext.dev = -1;
+#else
+ u->source_mixext.dev = mi.dev;
+#endif
+ /*
+ * The real way to pick a control on a mixer is with this
+ * number. Note that control numbers are unique across all
+ * mixers. So dev can just be ignored. When dev is included
+ * it will only be used to check for correct dev from userland.
+ * But it will not be used to select a mixer.
+ */
+ u->source_mixext.ctrl = i;
+
+ pa_log_debug («Control %d», u->source_mixext.ctrl);
+
+ if (ioctl (u->mixer_dsp_fd, SNDCTL_MIX_EXTINFO,
+ &(u->source_mixext)) == -1) {
+ pa_log_debug («SNDCTL_MIX_EXTINFO failed»);
+ continue;
+ }
+
+ pa_log_debug (» name : %s», u->source_mixext.extname);
+ pa_log_debug (» type : %s (%d)»,
+ mixer_ext_type_get_name (u->source_mixext.type),
+ u->source_mixext.type);
+ pa_log_debug (» maxval : %d», u->source_mixext.maxvalue);
+ pa_log_debug (» parent : %d», u->source_mixext.parent);
+ mixer_showflags (u->source_mixext.flags);
+
+ /*
+ * There may be more then one MIXF_RECVOL on a mixer. In fact
+ * for audioHD the can be three (line-in, mix-in, and cd-in).
+ * For a master gain it may be good to adjust all…
+ */
+ if ((u->source_mixext.flags & MIXF_RECVOL)) {
+ pa_log_debug («First REC control: %d», i);
+ u->mixer_source_control = i;
+ break;
+ }
+ }
+
+ if (u->mixer_source_control != -1) {
+ pa_log_debug («Setting OSS source callbacks.»);
+ pa_source_set_get_volume_callback(u->source, source_get_volume);
+ pa_source_set_set_volume_callback(u->source, source_set_volume);
+ u->source->n_volume_steps = 101;
+ do_close = FALSE;
+ } else {
+ pa_log_debug («Not setting OSS source callbacks.»);
+ }
+
+ if (do_close == TRUE) {
+ pa_close(u->mixer_dsp_fd);
+ u->mixer_dsp_fd = -1;
+ }
+ }
+
+#else
if (ioctl(fd, SOUND_MIXER_READ_DEVMASK, &u->mixer_devmask) < 0) pa_log_warn(«SOUND_MIXER_READ_DEVMASK failed: %s», pa_cstrerror(errno)); else { @@ -1445,11 +1810,14 @@ int pa__init(pa_module*m) { do_close = false; } } +#endif if (do_close) { pa_close(u->mixer_fd);
u->mixer_fd = -1;
+#ifndef HAVE_OSSV4
u->mixer_devmask = 0;
+#endif
}
}

@@ -1568,6 +1936,10 @@ void pa__done(pa_module*m) {
if (u->fd >= 0)
pa_close(u->fd);

+#ifdef HAVE_OSSV4
+ if (u->mixer_dsp_fd >= 0)
+ pa_close(u->mixer_dsp_fd);
+#endif
if (u->mixer_fd >= 0)
pa_close(u->mixer_fd);

diff -rupN pulseaudio-5.99.3.old/src/modules/oss/oss-util.c pulseaudio-5.99.3/src/modules/oss/oss-util.c
— pulseaudio-5.99.3.old/src/modules/oss/oss-util.c 2015-01-21 16:16:53.000000000 +0200
+++ pulseaudio-5.99.3/src/modules/oss/oss-util.c 2015-02-08 22:11:11.581982216 +0200
@@ -246,6 +246,190 @@ int pa_oss_set_fragments(int fd, int nfr
return 0;
}

+#ifdef HAVE_OSSV4
+static int
+oss4_mixer_slider_pack_volume (oss_mixext *mixext, int channels, const pa_cvolume *volume)
+{
+ int val = 0;
+ int lvol = 0;
+ int rvol = 0;
+ int lval = 0;
+ int rval = 0;
+
+ switch (mixext->type) {
+ case MIXT_MONOSLIDER:
+ case MIXT_MONOSLIDER16:
+ case MIXT_SLIDER:
+ lvol = volume->values[0] > PA_VOLUME_NORM ? PA_VOLUME_NORM : volume->values[0];
+ val = (lvol*mixext->maxvalue)/PA_VOLUME_NORM;
+ break;
+
+ case MIXT_STEREOSLIDER:
+ lvol = volume->values[0] > PA_VOLUME_NORM ? PA_VOLUME_NORM : volume->values[0];
+ lval = (lvol*mixext->maxvalue)/PA_VOLUME_NORM;
+ if (channels >= 2) {
+ rvol = volume->values[1] > PA_VOLUME_NORM ? PA_VOLUME_NORM : volume->values[1];
+ rval = (rvol*mixext->maxvalue)/PA_VOLUME_NORM;
+ }
+
+ val = ((rval & 0xff) << 8) | (lval & 0xff); + break; + + case MIXT_STEREOSLIDER16: + lvol = volume->values[0] > PA_VOLUME_NORM ? PA_VOLUME_NORM : volume->values[0];
+ lval = (lvol*mixext->maxvalue)/PA_VOLUME_NORM;
+ if (channels >= 2) {
+ rvol = volume->values[1] > PA_VOLUME_NORM ? PA_VOLUME_NORM : volume->values[1];
+ rval = (rvol*mixext->maxvalue)/PA_VOLUME_NORM;
+ }
+
+ val = ((rval & 0xffff) << 16) | (lval & 0xffff); + + break; + + default: + return 0; + } + + return val; +} + +static void +oss4_mixer_slider_unpack_volume (oss_mixext *mixext, int v, pa_cvolume * volume) +{ + uint32_t val, vol; + + val = (uint32_t) v; + switch (mixext->type) {
+ case MIXT_SLIDER:
+ vol = val;
+ volume->values[0] = PA_CLAMP_VOLUME((vol * PA_VOLUME_NORM) / mixext->maxvalue);
+ if (volume->channels >= 2) {
+ volume->values[1] = volume->values[0];
+ }
+ break;
+ case MIXT_MONOSLIDER:
+ /* oss repeats the value in the upper bits, as if it was stereo */
+ vol = val & 0x00ff;
+ volume->values[0] = PA_CLAMP_VOLUME((vol * PA_VOLUME_NORM) / mixext->maxvalue);
+ if (volume->channels >= 2) {
+ volume->values[1] = volume->values[0];
+ }
+ break;
+ case MIXT_MONOSLIDER16:
+ /* oss repeats the value in the upper bits, as if it was stereo */
+ vol = val & 0x0000ffff;
+ volume->values[0] = PA_CLAMP_VOLUME((vol * PA_VOLUME_NORM) / mixext->maxvalue);
+ if (volume->channels >= 2) {
+ volume->values[1] = volume->values[0];
+ }
+ break;
+ case MIXT_STEREOSLIDER:
+ vol = (val & 0x00ff);
+ volume->values[0] = PA_CLAMP_VOLUME((vol * PA_VOLUME_NORM) / mixext->maxvalue);
+ if (volume->channels >= 2) {
+ vol = (val & 0xff00) >> 8;
+ volume->values[1] = PA_CLAMP_VOLUME((vol * PA_VOLUME_NORM) / mixext->maxvalue);
+ }
+ break;
+ case MIXT_STEREOSLIDER16:
+ vol = (val & 0x0000ffff);
+ volume->values[0] = PA_CLAMP_VOLUME((vol * PA_VOLUME_NORM) / mixext->maxvalue);
+ if (volume->channels >= 2) {
+ vol = (val & 0xffff0000) >> 16;
+ volume->values[1] = PA_CLAMP_VOLUME((vol * PA_VOLUME_NORM) / mixext->maxvalue);
+ }
+ break;
+ default:
+ return;
+ }
+}
+
+static int
+oss4_mixer_get_control_val (int fd, oss_mixext *mixext, int *val)
+{
+ oss_mixer_value ossval = { 0, };
+
+ /* ossval.dev = mixext->dev; */
+ ossval.dev = -1; /* if -1 on entry then is ignored */
+ /*
+ * The real way to pick a control on a mixer is with this number.
+ * Note that control numbers are uniq across all mixers. So dev
+ * can just be ignored. When dev is included it will only be used
+ * to check for correct dev from userland. But it will not be used
+ * to select a mixer.
+ */
+ ossval.ctrl = mixext->ctrl;
+ ossval.timestamp = mixext->timestamp;
+
+ if (ioctl (fd, SNDCTL_MIX_READ, &ossval) == -1) {
+ pa_log_debug («SNDCTL_MIX_READ failed»);
+ *val = 0;
+ return -1;
+ }
+
+ *val = ossval.value;
+ pa_log_debug («got value 0x%08x from %s», *val, mixext->extname);
+ return 0;
+}
+
+static int
+oss4_mixer_set_control_val (int fd, oss_mixext *mixext, int val)
+{
+ oss_mixer_value ossval = { 0, };
+
+ /* ossval.dev = mixext->dev; */
+ ossval.dev = -1; /* if -1 on entry then is ignored */
+ /*
+ * The real way to pick a control on a mixer is with this number.
+ * Note that control numbers are uniq across all mixers. So dev
+ * can just be ignored. When dev is included it will only be used
+ * to check for correct dev from userland. But it will not be used
+ * to select a mixer.
+ */
+ ossval.ctrl = mixext->ctrl;
+ ossval.timestamp = mixext->timestamp;
+ ossval.value = val;
+
+ if (ioctl (fd, SNDCTL_MIX_WRITE, &ossval) == -1) {
+ pa_log_debug («SNDCTL_MIX_WRITE failed»);
+ return -1;
+ }
+
+ pa_log_debug («set value 0x%08x on %s», val, mixext->extname);
+ return 0;
+}
+
+int pa_oss_get_volume(int fd, oss_mixext *mixext, const pa_sample_spec *ss, pa_cvolume *volume) {
+ int v = 0;
+
+ if (oss4_mixer_get_control_val (fd, mixext, &v) != 0) {
+ pa_log_debug («Getting volume failed»);
+ return -1;
+ }
+
+ pa_cvolume_reset(volume, ss->channels);
+
+ oss4_mixer_slider_unpack_volume (mixext, v, volume);
+
+ return 0;
+}
+
+int pa_oss_set_volume(int fd, oss_mixext *mixext, const pa_sample_spec *ss, const pa_cvolume *volume) {
+ int val = 0;
+
+ val = oss4_mixer_slider_pack_volume (mixext, ss->channels, volume);
+
+ if (oss4_mixer_set_control_val (fd, mixext, val) != 0) {
+ pa_log_debug («Setting volume failed»);
+ return -1;
+ }
+
+ return 0;
+}
+
+#else
+
int pa_oss_get_volume(int fd, unsigned long mixer, const pa_sample_spec *ss, pa_cvolume *volume) {
char cv[PA_CVOLUME_SNPRINT_VERBOSE_MAX];
unsigned vol;
@@ -288,6 +472,7 @@ int pa_oss_set_volume(int fd, unsigned l
pa_log_debug(«Wrote mixer settings: %s», pa_cvolume_snprint(cv, sizeof(cv), volume));
return 0;
}
+#endif

static int get_device_number(const char *dev) {
const char *p, *e;
@@ -386,9 +571,11 @@ int pa_oss_get_hw_description(const char
return r;
}

-static int open_mixer(const char *mixer) {
+int pa_oss_open_mixer(const char *mixer) {
int fd;

+ pa_log_debug («Opening device %s», mixer);
+
if ((fd = pa_open_cloexec(mixer, O_RDWR|O_NDELAY, 0)) >= 0)
return fd;

@@ -400,19 +587,22 @@ int pa_oss_open_mixer_for_device(const c
char *fn;
int fd;

– if ((n = get_device_number(device)) < 0)
+ if ((n = get_device_number(device)) < 0) { + pa_log_debug («Cannot find device»); return -1; + } if (n == 0) – if ((fd = open_mixer(«/dev/mixer»)) >= 0)
+ if ((fd = pa_oss_open_mixer(«/dev/mixer»)) >= 0)
return fd;

fn = pa_sprintf_malloc(«/dev/mixer%i», n);
– fd = open_mixer(fn);
+ fd = pa_oss_open_mixer(fn);
pa_xfree(fn);

if (fd < 0)
pa_log_warn(«Failed to open mixer ‘%s’: %s», device, pa_cstrerror(errno));
+ else

return fd;
}
diff -rupN pulseaudio-5.99.3.old/src/modules/oss/oss-util.h pulseaudio-5.99.3/src/modules/oss/oss-util.h
— pulseaudio-5.99.3.old/src/modules/oss/oss-util.h 2015-01-21 16:16:53.000000000 +0200
+++ pulseaudio-5.99.3/src/modules/oss/oss-util.h 2015-02-08 22:11:11.582249622 +0200
@@ -29,11 +29,21 @@ int pa_oss_auto_format(int fd, pa_sample

int pa_oss_set_fragments(int fd, int frags, int frag_size);

+#define HAVE_OSSV4
+
+#ifdef HAVE_OSSV4
+int pa_oss_set_volume(int fd, oss_mixext *mixext, const pa_sample_spec *ss, const pa_cvolume *volume);
+int pa_oss_get_volume(int fd, oss_mixext *mixext, const pa_sample_spec *ss, pa_cvolume *volume);
+
+#else
+
int pa_oss_set_volume(int fd, unsigned long mixer, const pa_sample_spec *ss, const pa_cvolume *volume);
int pa_oss_get_volume(int fd, unsigned long mixer, const pa_sample_spec *ss, pa_cvolume *volume);
+#endif

int pa_oss_get_hw_description(const char *dev, char *name, size_t l);

int pa_oss_open_mixer_for_device(const char *device);
+int pa_oss_open_mixer(const char *device);

#endif
diff -rupN pulseaudio-5.99.3.old/src/pulse/sample.h pulseaudio-5.99.3/src/pulse/sample.h
— pulseaudio-5.99.3.old/src/pulse/sample.h 2015-01-21 16:16:53.000000000 +0200
+++ pulseaudio-5.99.3/src/pulse/sample.h 2015-02-08 22:11:11.582624201 +0200
@@ -121,7 +121,9 @@ PA_C_DECL_BEGIN
#if defined(__sparc__) && defined(_BIG_ENDIAN)
#define WORDS_BIGENDIAN
#endif

+#if defined(_BIG_ENDIAN)
+#define WORDS_BIGENDIAN
+#endif
#endif

/** Maximum number of allowed channels */
diff -rupN pulseaudio-5.99.3.old/src/pulsecore/core-scache.h pulseaudio-5.99.3/src/pulsecore/core-scache.h
— pulseaudio-5.99.3.old/src/pulsecore/core-scache.h 2015-01-21 16:16:53.000000000 +0200
+++ pulseaudio-5.99.3/src/pulsecore/core-scache.h 2015-02-08 22:11:11.582922144 +0200
@@ -25,7 +25,6 @@
#include <pulsecore/memchunk.h> #include <pulsecore/sink.h>

-#define PA_SCACHE_ENTRY_SIZE_MAX (1024*1024*16)

typedef struct pa_scache_entry {
uint32_t index;
@@ -65,4 +64,5 @@ size_t pa_scache_total_size(pa_core *c);

void pa_scache_unload_unused(pa_core *c);

+#define PA_SCACHE_ENTRY_SIZE_MAX (1024*1024*16)
#endif
diff -rupN pulseaudio-5.99.3.old/src/pulsecore/shm.c pulseaudio-5.99.3/src/pulsecore/shm.c
— pulseaudio-5.99.3.old/src/pulsecore/shm.c 2015-01-21 16:16:53.000000000 +0200
+++ pulseaudio-5.99.3/src/pulsecore/shm.c 2015-02-08 22:11:11.583260666 +0200
@@ -371,8 +371,11 @@ int pa_shm_cleanup(void) {
if (strncmp(de->d_name, «pulse-shm-«, SHM_ID_LEN))
#endif
continue;

+#if defined(__sun)
+ if (pa_atou(de->d_name + 10, &id) < 0) +#else if (pa_atou(de->d_name + SHM_ID_LEN, &id) < 0)
+#endif
continue;

if (pa_shm_attach(&seg, id, false) < 0) diff -rupN pulseaudio-5.99.3.old/src/utils/padsp.c pulseaudio-5.99.3/src/utils/padsp.c — pulseaudio-5.99.3.old/src/utils/padsp.c 2015-01-21 16:16:53.000000000 +0200 +++ pulseaudio-5.99.3/src/utils/padsp.c 2015-02-08 22:17:07.921244432 +0200 @@ -2275,6 +2275,7 @@ static int dsp_ioctl(fd_info *i, unsigne break; } +#ifndef __sun case SOUND_PCM_READ_RATE: debug(DEBUG_LEVEL_NORMAL, __FILE__»: SOUND_PCM_READ_RATE\n»); @@ -2298,6 +2299,7 @@ static int dsp_ioctl(fd_info *i, unsigne *(int*) argp = pa_sample_size(&i->sample_spec)*8;
pa_threaded_mainloop_unlock(i->mainloop);
break;
+#endif

case SNDCTL_DSP_GETOPTR: {
count_info *info;
@@ -2368,7 +2370,7 @@ fail:
return ret;
}

-#ifdef sun
+#ifdef __sun
int ioctl(int fd, int request, …) {
#else
int ioctl(int fd, unsigned long request, …) {

New Book on Filter Design for Satellite Communications

Posted in Χωρίς κατηγορία by asyropoulos on Φεβρουαρίου 7, 2015

My friend Efstratios Doumanis is the co-author of a new book entitled Filter Design for Satellite Communications: Helical Resonator Technology.  I am no expert in filter design but I am sure Efstratios and his co-authors have done a splendid job!