/* StartRecording: open the device for recording. XXX this routine is almost identical to snd_Start(). The two should be factored into a single function! */ static int sound_StartRecording(int desiredSamplesPerSec, int stereo0, int semaIndex0) { AuElement elements[2]; /* elements for the NAS flow to assemble: element 0 = physical input element 1 = client export */ AuDeviceID device; /* physical device ID to use */ DPRINTF("StartRecording\n"); sound_Stop(); DPRINTF("opening server\n"); server = AuOpenServer(NULL, 0, NULL, 0, NULL, NULL); if(server == NULL) { DPRINTF("failed to open audio server\n"); return false; } /* XXX check protocol version of the server */ semaIndex= semaIndex0; stereo= stereo0; sampleRate= desiredSamplesPerSec; device= choose_nas_device(server, desiredSamplesPerSec, stereo, 1); if(device == AuNone) { DPRINTF("no available device on the server!\n"); AuCloseServer(server); server = NULL; return false; } /* record format info */ fmtBytes=2; fmtSigned=1; fmtStereo=stereo; fmtIsBigendian=0; recording=1; /* create a flow to read from */ DPRINTF("creating flow\n"); flow = AuCreateFlow(server, NULL); /* create client and device elements to record with */ DPRINTF("creating elements\n"); AuMakeElementImportDevice(&elements[0], desiredSamplesPerSec, /* XXX should use the actual sampling rate of device */ device, AuUnlimitedSamples, 0, NULL); AuMakeElementExportClient(&elements[1], 0, desiredSamplesPerSec, AuFormatLinearSigned16LSB, /* XXX this should be chosen based on the platform */ stereo ? 2 : 1, AuTrue, 1000000, /* was AuUnlimitedSamples */ 1000, /* water mark: go ahead and send frequently! */ 0, NULL); /* set up the flow with these elements */ AuSetElements(server, flow, AuTrue, 2, elements, NULL); /* start her up */ DPRINTF("starting flow\n"); AuStartFlow(server, flow, NULL); AuFlush(server); /* initialize the space indication */ bytesAvail = 0; /* arrange to be informed when events come in from the server */ aioEnable(AuServerConnectionNumber(server), NULL, AIO_EXT); aioHandle(AuServerConnectionNumber(server), handleAudioEvents, AIO_W); return true; }
static int NAS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { AuElement elms[3]; int buffer_size; SDL_AudioFormat test_format, format; /* Initialize all variables that we clean on shutdown */ this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc((sizeof *this->hidden)); if (this->hidden == NULL) { return SDL_OutOfMemory(); } SDL_zerop(this->hidden); /* Try for a closest match on audio format */ format = 0; for (test_format = SDL_FirstAudioFormat(this->spec.format); !format && test_format;) { format = sdlformat_to_auformat(test_format); if (format == AuNone) { test_format = SDL_NextAudioFormat(); } } if (format == 0) { return SDL_SetError("NAS: Couldn't find any hardware audio formats"); } this->spec.format = test_format; this->hidden->aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL); if (this->hidden->aud == 0) { return SDL_SetError("NAS: Couldn't open connection to NAS server"); } this->hidden->dev = find_device(this); if ((this->hidden->dev == AuNone) || (!(this->hidden->flow = NAS_AuCreateFlow(this->hidden->aud, 0)))) { return SDL_SetError("NAS: Couldn't find a fitting device on NAS server"); } buffer_size = this->spec.freq; if (buffer_size < 4096) buffer_size = 4096; if (buffer_size > 32768) buffer_size = 32768; /* So that the buffer won't get unmanageably big. */ /* Calculate the final parameters for this audio specification */ SDL_CalculateAudioSpec(&this->spec); if (iscapture) { AuMakeElementImportDevice(elms, this->spec.freq, this->hidden->dev, AuUnlimitedSamples, 0, NULL); AuMakeElementExportClient(elms + 1, 0, this->spec.freq, format, this->spec.channels, AuTrue, buffer_size, buffer_size, 0, NULL); } else { AuMakeElementImportClient(elms, this->spec.freq, format, this->spec.channels, AuTrue, buffer_size, buffer_size / 4, 0, NULL); AuMakeElementExportDevice(elms + 1, 0, this->hidden->dev, this->spec.freq, AuUnlimitedSamples, 0, NULL); } NAS_AuSetElements(this->hidden->aud, this->hidden->flow, AuTrue, 2, elms, NULL); NAS_AuRegisterEventHandler(this->hidden->aud, AuEventHandlerIDMask, 0, this->hidden->flow, event_handler, (AuPointer) this); NAS_AuStartFlow(this->hidden->aud, this->hidden->flow, NULL); /* Allocate mixing buffer */ 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); } /* We're ready to rock and roll. :-) */ return 0; }