OSS emulation, period size, and start/stop thresholds

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I'm writing an application to run on an embedded ARM with very little
hardware buffering capacity on its audio interface.  I also wrote an
ALSA driver (to be released under the GPL) for this interface, which
works rather nicely with aplay as long as I tune the period size and
thresholds and so forth, more or less like so:

aplay -C -t wav -c 1 -d 3600 -f s16_le --period-size=40
--buffer-size=160 --start-delay=3500 | aplay -P -c 1 --period-size=40
--buffer-size=160 --avail-min=5500 --start-delay=10500

(That's with alsa-lib 1.0.14rc2, unaltered, and alsa-utils 1.0.14rc2,
with a patch to support real-time scheduling and fix all the places
where output that should go to stderr is sent to stdout.  That patch
is attached.)

Now, an earlier version of the application was implemented against a
one-off driver for different hardware, and just used read()/write() to
deliver data to the driver.  It would be nice to be able to open the
/dev/dsp OSS emulation device, ioctl it into the right format and
tunings, and leave the read()/write() alone, saving the rework for a
callback model for another day.

Does snd_pcm_oss have reasonable ioctl's to force renegotiation about
period size and start/stop thresholds, roughly equivalent to the
parameters above?

Thanks in advance,
- Michael
diff -ur alsa-utils-1.0.14rc2/aplay/aplay.c alsa-utils-1.0.14rc2-patched/aplay/aplay.c
--- alsa-utils-1.0.14rc2/aplay/aplay.c	2007-02-06 14:22:54.000000000 -0800
+++ alsa-utils-1.0.14rc2-patched/aplay/aplay.c	2007-02-06 14:29:37.000000000 -0800
@@ -27,6 +27,7 @@
  */
 
 #define _GNU_SOURCE
+#include <sched.h>
 #include <stdio.h>
 #include <malloc.h>
 #include <unistd.h>
@@ -149,7 +150,7 @@
 static void usage(char *command)
 {
 	snd_pcm_format_t k;
-	printf(
+	fprintf(stderr,
 _("Usage: %s [OPTION]... [FILE]...\n"
 "\n"
 "-h, --help              help\n"
@@ -177,17 +178,17 @@
 "-v, --verbose           show PCM structure and setup (accumulative)\n"
 "-I, --separate-channels one file for each channel\n")
 		, command);
-	printf(_("Recognized sample formats are:"));
+	fprintf(stderr, _("Recognized sample formats are:"));
 	for (k = 0; k < SND_PCM_FORMAT_LAST; ++k) {
 		const char *s = snd_pcm_format_name(k);
 		if (s)
-			printf(" %s", s);
+			fprintf(stderr, " %s", s);
 	}
-	printf(_("\nSome of these may not be available on selected hardware\n"));
-	printf(_("The availabled format shortcuts are:\n"));
-	printf(_("-f cd (16 bit little endian, 44100, stereo)\n"));
-	printf(_("-f cdr (16 bit big endian, 44100, stereo)\n"));
-	printf(_("-f dat (16 bit little endian, 48000, stereo)\n"));
+	fprintf(stderr, _("\nSome of these may not be available on selected hardware\n"));
+	fprintf(stderr, _("The availabled format shortcuts are:\n"));
+	fprintf(stderr, _("-f cd (16 bit little endian, 44100, stereo)\n"));
+	fprintf(stderr, _("-f cdr (16 bit big endian, 44100, stereo)\n"));
+	fprintf(stderr, _("-f dat (16 bit little endian, 48000, stereo)\n"));
 }
 
 static void device_list(void)
@@ -204,7 +205,7 @@
 		error(_("no soundcards found..."));
 		return;
 	}
-	printf(_("**** List of %s Hardware Devices ****\n"),
+	fprintf(stderr, _("**** List of %s Hardware Devices ****\n"),
 	       snd_pcm_stream_name(stream));
 	while (card >= 0) {
 		char name[32];
@@ -233,20 +234,20 @@
 					error("control digital audio info (%i): %s", card, snd_strerror(err));
 				continue;
 			}
-			printf(_("card %i: %s [%s], device %i: %s [%s]\n"),
+			fprintf(stderr, _("card %i: %s [%s], device %i: %s [%s]\n"),
 				card, snd_ctl_card_info_get_id(info), snd_ctl_card_info_get_name(info),
 				dev,
 				snd_pcm_info_get_id(pcminfo),
 				snd_pcm_info_get_name(pcminfo));
 			count = snd_pcm_info_get_subdevices_count(pcminfo);
-			printf( _("  Subdevices: %i/%i\n"),
+			fprintf(stderr, _("  Subdevices: %i/%i\n"),
 				snd_pcm_info_get_subdevices_avail(pcminfo), count);
 			for (idx = 0; idx < (int)count; idx++) {
 				snd_pcm_info_set_subdevice(pcminfo, idx);
 				if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
 					error("control digital audio playback info (%i): %s", card, snd_strerror(err));
 				} else {
-					printf(_("  Subdevice #%i: %s\n"),
+					fprintf(stderr, _("  Subdevice #%i: %s\n"),
 						idx, snd_pcm_info_get_subdevice_name(pcminfo));
 				}
 			}
@@ -276,17 +277,17 @@
 		io = snd_device_name_get_hint(*n, "IOID");
 		if (io != NULL && strcmp(io, filter) == 0)
 			goto __end;
-		printf("%s\n", name);
+		fprintf(stderr, "%s\n", name);
 		if ((descr1 = descr) != NULL) {
-			printf("    ");
+			fprintf(stderr, "    ");
 			while (*descr1) {
 				if (*descr1 == '\n')
-					printf("\n    ");
+					fprintf(stderr, "\n    ");
 				else
-					putchar(*descr1);
+					putc(*descr1, stderr);
 				descr1++;
 			}
-			putchar('\n');
+			putc('\n', stderr);
 		}
 	      __end:
 	      	if (name != NULL)
@@ -302,13 +303,13 @@
 
 static void version(void)
 {
-	printf("%s: version " SND_UTIL_VERSION_STR " by Jaroslav Kysela <perex@xxxxxxx>\n", command);
+	fprintf(stderr, "%s: version " SND_UTIL_VERSION_STR " by Jaroslav Kysela <perex@xxxxxxx>\n", command);
 }
 
 static void signal_handler(int sig)
 {
 	if (verbose==2)
-		putchar('\n');
+		putc('\n', stderr);
 	if (!quiet_mode)
 		fprintf(stderr, _("Aborted by signal %s...\n"), strsignal(sig));
 	if (stream == SND_PCM_STREAM_CAPTURE) {
@@ -515,10 +516,16 @@
 			interleaved = 0;
 			break;
 		case 'P':
+		{	struct sched_param param = { 0 };
+			param.sched_priority = 60;
+			sched_setscheduler(0, SCHED_FIFO, &param);	}
 			stream = SND_PCM_STREAM_PLAYBACK;
 			command = "aplay";
 			break;
 		case 'C':
+		{	struct sched_param param = { 0 };
+			param.sched_priority = 40;
+			sched_setscheduler(0, SCHED_FIFO, &param);	}
 			stream = SND_PCM_STREAM_CAPTURE;
 			command = "arecord";
 			start_delay = 1;
@@ -605,7 +612,7 @@
 			capturev(&argv[optind], argc - optind);
 	}
 	if (verbose==2)
-		putchar('\n');
+		putc('\n', stderr);
 	snd_pcm_close(handle);
 	free(audiobuf);
       __end:
@@ -1212,30 +1219,30 @@
 		if(perc>maxperc)
 			maxperc=perc;
 
-		putchar('\r');
+		putc('\r', stderr);
 		for (val = 0; val <= perc / 2 && val < 50; val++)
-			putchar('#');
+			putc('#', stderr);
 		for (; val < maxperc / 2 && val < 50; val++)
-			putchar(' ');
-		putchar('+');
+			putc(' ', stderr);
+		putc('+', stderr);
 		for (++val; val < 50; val++)
-			putchar(' ');
+			putc(' ', stderr);
 
-		printf("| %02i%%", maxperc);
+		fprintf(stderr, "| %02i%%", maxperc);
 		if (perc>99)
-			printf(_(" !clip  "));
+			fprintf(stderr, _(" !clip  "));
 
-		fflush(stdout);
+		fflush(stderr);
 	}
 	else if(verbose==3) {
-		printf(_("Max peak (%li samples): 0x%08x "), (long)ocount, max_peak);
+		fprintf(stderr, _("Max peak (%li samples): 0x%08x "), (long)ocount, max_peak);
 		for (val = 0; val < 20; val++)
 			if (val <= perc / 5)
-				putchar('#');
+				putc('#', stderr);
 			else
-				putchar(' ');
-		printf(" %i%%\n", perc);
-		fflush(stdout);
+				putc(' ', stderr);
+		fprintf(stderr, " %i%%\n", perc);
+		fflush(stderr);
 	}
 }
 
@@ -2124,7 +2131,7 @@
 
 	do {
 		/* open a file to write */
-		if(!tostdout) {
+		if (!tostdout) {
 			/* upon the second file we start the numbering scheme */
 			if (filecount) {
 				filecount = new_capture_file(orig_name, namebuf,
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Alsa-devel mailing list
Alsa-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/alsa-devel

[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux