dsp: Implemented audio capture support.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
diff --git a/src/audio/dsp/SDL_dspaudio.c b/src/audio/dsp/SDL_dspaudio.c
index f267f84..a5a31b3 100644
--- a/src/audio/dsp/SDL_dspaudio.c
+++ b/src/audio/dsp/SDL_dspaudio.c
@@ -107,9 +107,8 @@ DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
if (this->hidden->audio_fd < 0) {
return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
}
- this->hidden->mixbuf = NULL;
- /* Make the file descriptor use blocking writes with fcntl() */
+ /* Make the file descriptor use blocking i/o with fcntl() */
{
long ctlflags;
ctlflags = fcntl(this->hidden->audio_fd, F_GETFL);
@@ -236,12 +235,14 @@ DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
#endif
/* Allocate mixing buffer */
- this->hidden->mixlen = this->spec.size;
- this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
- if (this->hidden->mixbuf == NULL) {
- return SDL_OutOfMemory();
+ if (!iscapture) {
+ this->hidden->mixlen = this->spec.size;
+ this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
+ if (this->hidden->mixbuf == NULL) {
+ return SDL_OutOfMemory();
+ }
+ SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
}
- SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
/* We're ready to rock and roll. :-) */
return 0;
@@ -251,14 +252,13 @@ DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
static void
DSP_PlayDevice(_THIS)
{
- const Uint8 *mixbuf = this->hidden->mixbuf;
- const int mixlen = this->hidden->mixlen;
- if (write(this->hidden->audio_fd, mixbuf, mixlen) == -1) {
+ struct SDL_PrivateAudioData *h = this->hidden;
+ if (write(h->audio_fd, h->mixbuf, h->mixlen) == -1) {
perror("Audio write");
SDL_OpenedAudioDeviceDisconnected(this);
}
#ifdef DEBUG_AUDIO
- fprintf(stderr, "Wrote %d bytes of audio data\n", mixlen);
+ fprintf(stderr, "Wrote %d bytes of audio data\n", h->mixlen);
#endif
}
@@ -269,6 +269,30 @@ DSP_GetDeviceBuf(_THIS)
}
static int
+DSP_CaptureFromDevice(_THIS, void *buffer, int buflen)
+{
+ return (int) read(this->hidden->audio_fd, buffer, buflen);
+}
+
+static void
+DSP_FlushCapture(_THIS)
+{
+ struct SDL_PrivateAudioData *h = this->hidden;
+ audio_buf_info info;
+ if (ioctl(h->audio_fd, SNDCTL_DSP_GETISPACE, &info) == 0) {
+ while (info.bytes > 0) {
+ char buf[512];
+ const size_t len = SDL_min(sizeof (buf), info.bytes);
+ const ssize_t br = read(h->audio_fd, buf, len);
+ if (br <= 0) {
+ break;
+ }
+ info.bytes -= br;
+ }
+ }
+}
+
+static int
DSP_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
@@ -277,8 +301,11 @@ DSP_Init(SDL_AudioDriverImpl * impl)
impl->PlayDevice = DSP_PlayDevice;
impl->GetDeviceBuf = DSP_GetDeviceBuf;
impl->CloseDevice = DSP_CloseDevice;
+ impl->CaptureFromDevice = DSP_CaptureFromDevice;
+ impl->FlushCapture = DSP_FlushCapture;
impl->AllowsArbitraryDeviceNames = 1;
+ impl->HasCaptureSupport = SDL_TRUE;
return 1; /* this audio target is available. */
}