ports/58227: patch to unbreak audio/sphinx port
Andriy Gapon
agapon at cv-nj.com
Sat Oct 18 18:30:13 UTC 2003
>Number: 58227
>Category: ports
>Synopsis: patch to unbreak audio/sphinx port
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-ports-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sat Oct 18 11:30:11 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator: Andriy Gapon
>Release: FreeBSD 4.8-RELEASE-p13 i386
>Organization:
>Environment:
System: FreeBSD 4.8-RELEASE-p13 #1: Fri Oct 17 23:03:22 EDT 2003 i386
>Description:
audio/sphinx port of Sphinx2 speech recognition software has been long broken
and marked IGNORE due to a number of bugs in working with FreeBSD OSS driver
e.g. dsp device is opened in nonblocking mode but EAGAIN condition is not
properly handled.
>How-To-Repeat:
try to build it after removing IGNORE line from Makefile and run sphinx2-demo
>Fix:
after applying the attached patch I was able to successfully run sphinx2-demo.
to unbreak the port this patch needs to be put in files/ subdirectory and
IGNORE line needs to be removed fro the Makefile.
--- patch-aa begins here ---
diff -uNr sphinx2-0.4.orig/src/examples/tty-continuous.c sphinx2-0.4/src/examples/tty-continuous.c
--- src/examples/tty-continuous.c Thu Oct 16 19:17:44 2003
+++ src/examples/tty-continuous.c Thu Oct 16 20:01:54 2003
@@ -175,7 +175,6 @@
* listening until current utterance completely decoded
*/
ad_stop_rec (ad);
- while (ad_read (ad, adbuf, 4096) >= 0);
cont_ad_reset (cont);
printf ("Stopped listening, please wait...\n"); fflush (stdout);
diff -uNr sphinx2-0.4.orig/src/libsphinx2ad/ad_oss_bsd.c sphinx2-0.4/src/libsphinx2ad/ad_oss_bsd.c
--- src/libsphinx2ad/ad_oss_bsd.c Thu Oct 16 19:17:44 2003
+++ src/libsphinx2ad/ad_oss_bsd.c Thu Oct 16 19:59:18 2003
@@ -72,14 +72,11 @@
#define SPS_EPSILON 200
-#ifndef SNDCTL_DSP_SETDUPLEX
-#define SNDCTL_DSP_SETDUPLEX -1
-#endif
ad_rec_t *ad_open_sps (int32 sps) {
ad_rec_t *handle;
int32 dspFD, mixerFD;
- int32 nonBlocking=1, sourceMic=1, inputGain=INPUT_GAIN;
+ int32 sourceMic=1, inputGain=INPUT_GAIN;
int32 audioFormat=AUDIO_FORMAT;
int32 dspCaps=0;
int32 sampleRate;
@@ -96,7 +93,6 @@
}
sampleRate = sps;
- /* Used to have O_NDELAY. */
if((dspFD = open ("/dev/dsp", O_RDONLY))<0){
if (errno == EBUSY)
fprintf(stderr, "Audio device busy\n");
@@ -105,18 +101,6 @@
return NULL;
}
- if (ioctl (dspFD, SNDCTL_DSP_SYNC, 0) < 0){
- fprintf(stderr, "Audio ioctl(SYNC) failed: %s\n", strerror(errno));
- close (dspFD);
- return NULL;
- }
-
- if (ioctl (dspFD, SNDCTL_DSP_RESET, 0) < 0){
- fprintf(stderr, "Audio ioctl(RESET) failed: %s\n", strerror(errno));
- close (dspFD);
- return NULL;
- }
-
if (ioctl (dspFD, SNDCTL_DSP_SETFMT, &audioFormat) < 0){
fprintf(stderr, "Audio ioctl(SETFMT 0x%x) failed: %s\n", audioFormat, strerror(errno));
close (dspFD);
@@ -139,12 +123,6 @@
return NULL;
}
- if (ioctl (dspFD, SNDCTL_DSP_NONBLOCK, &nonBlocking) < 0) {
- fprintf(stderr, "ioctl(NONBLOCK) failed: %s\n", strerror(errno));
- close (dspFD);
- return NULL;
- }
-
if (ioctl (dspFD, SNDCTL_DSP_GETCAPS, &dspCaps) < 0) {
fprintf(stderr, "ioctl(GETCAPS) failed: %s\n", strerror(errno));
close (dspFD);
@@ -161,8 +139,6 @@
printf("DSP %s memory map capability.\n", (dspCaps&DSP_CAP_MMAP)?"has":"does not have");
#endif
- if ((dspCaps & DSP_CAP_DUPLEX) && (ioctl (dspFD, SNDCTL_DSP_SETDUPLEX, 0) < 0))
- fprintf(stderr, "ioctl(SETDUPLEX) failed: %s\n", strerror(errno));
/* Patched by N. Roy (nickr at ri.cmu.edu), 99/7/23.
Previously, mixer was set through dspFD. This is incorrect. Should
@@ -210,10 +186,10 @@
}
handle->dspFD = dspFD;
- handle->recording = 0;
handle->sps = sps;
handle->bps = sizeof(int16);
-
+ handle->recording = 1;
+
return(handle);
}
@@ -224,15 +200,10 @@
int32 ad_close (ad_rec_t *handle)
{
- if (handle->dspFD < 0)
- return AD_ERR_NOT_OPEN;
-
if (handle->recording) {
- if (ad_stop_rec (handle) < 0)
- return AD_ERR_GEN;
+ ad_stop_rec (handle);
}
- close (handle->dspFD);
free(handle);
return(0);
@@ -240,48 +211,62 @@
int32 ad_start_rec (ad_rec_t *handle)
{
- if (handle->dspFD < 0)
- return AD_ERR_NOT_OPEN;
-
- if (handle->recording)
- return AD_ERR_GEN;
+
+ if (!handle->recording) {
+
+ int32 dspFD;
+ int32 audioFormat=AUDIO_FORMAT;
+ int32 sampleRate=handle->sps;
+
+ if((dspFD = open ("/dev/dsp", O_RDONLY))<0){
+ if (errno == EBUSY)
+ fprintf(stderr, "Audio device busy\n");
+ else
+ fprintf(stderr, "Failed to open audio device: %s\n", strerror(errno));
+ return AD_ERR_GEN;
+ }
- /* Sample rate, format, input mix settings, &c. are configured
- * with ioctl(2) calls under Linux. It makes more sense to handle
- * these at device open time and consider the state of the device
- * to be fixed until closed.
- */
+ if (ioctl (dspFD, SNDCTL_DSP_SETFMT, &audioFormat) < 0){
+ fprintf(stderr, "Audio ioctl(SETFMT 0x%x) failed: %s\n", audioFormat, strerror(errno));
+ close (dspFD);
+ return AD_ERR_GEN;
+ }
+ if (audioFormat != AUDIO_FORMAT) {
+ fprintf(stderr, "Audio ioctl(SETFMT): 0x%x, expected: 0x%x\n", audioFormat, AUDIO_FORMAT);
+ close (dspFD);
+ return AD_ERR_GEN;
+ }
- handle->recording = 1;
-
- /* rkm at cs: This doesn't actually do anything. How do we turn recording on/off? */
+ if (ioctl (dspFD, SNDCTL_DSP_SPEED, &sampleRate) < 0) {
+ fprintf(stderr, "Audio ioctl(SPEED %d) failed %s\n", sampleRate, strerror(errno));
+ close (dspFD);
+ return AD_ERR_GEN;
+ }
+ if (sampleRate != handle->sps) {
+ fprintf(stderr, "Audio ioctl(SPEED): %d, expected: %d\n", sampleRate, handle->sps);
+ close (dspFD);
+ return AD_ERR_GEN;
+ }
+ handle->dspFD = dspFD;
+ handle->recording = 1;
+ }
return(0);
}
int32 ad_stop_rec (ad_rec_t *handle)
{
- if (handle->dspFD < 0)
- return AD_ERR_NOT_OPEN;
-
- if (! handle->recording)
- return AD_ERR_GEN;
-
- if (ioctl (handle->dspFD, SNDCTL_DSP_SYNC, 0) < 0) {
- fprintf(stderr, "Audio ioctl(SYNC) failed: %s\n", strerror(errno));
- return AD_ERR_GEN;
- }
-
- handle->recording = 0;
-
+ if (handle->recording) {
+ close (handle->dspFD);
+ handle->dspFD = -1;
+ handle->recording = 0;
+ }
return (0);
}
int32 ad_read (ad_rec_t *handle, int16 *buf, int32 max)
{
- int32 length;
-
- length = max * handle->bps; /* #samples -> #bytes */
+ int32 length = max * handle->bps; /* #samples -> #bytes */
if ((length = read (handle->dspFD, buf, length)) > 0) {
#if 0
@@ -292,7 +277,7 @@
}
if (length < 0) {
- fprintf(stderr, "Audio read error\n");
+ perror("Audio read error");
return AD_ERR_GEN;
}
--- patch-aa ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-ports-bugs
mailing list