// **** Audio card support // Aquire and enabled audio card // return 0 if ok, -1 if failed // $$kk: 08.12.98 merge: modified this function int HAE_AquireAudioCard(void *context, UINT32 sampleRate, UINT32 channels, UINT32 bits) { int flag; long error; #ifdef DEBUG_AUDIO jio_fprintf(stderr, "Acquire audio card(sampleRate=%d, channels=%d, bits=%d\n", sampleRate, channels, bits); #endif flag = 0; g_activeDoubleBuffer = FALSE; g_shutDownDoubleBuffer = TRUE; g_audioFramesToGenerate = HAE_GetMaxSamplePerSlice(); #ifdef TODO // ask Kara switch (sampleRate) { case 44100: g_audioFramesToGenerate = HAE_GetMaxSamplePerSlice(); break; case 11025: /* [sbb fix] why is this case thrown away? */ sampleRate = 22050; case 22050: g_audioFramesToGenerate = HAE_GetMaxSamplePerSlice()/2; break; } #endif /* we're going to build this many buffers at a time */ g_synthFramesPerBlock = HAE_LINUX_FRAMES_PER_BLOCK; g_audioPeriodSleepTime = HAE_LINUX_SOUND_PERIOD; g_bitSize = bits; g_channels = channels; if (bits == 8) { g_audioByteBufferSize = (sizeof(char) * g_audioFramesToGenerate); } else { g_audioByteBufferSize = (sizeof(short int) * g_audioFramesToGenerate); } g_audioByteBufferSize *= channels; flag = 1; /* allocate buffer blocks */ g_audioBufferBlock = HAE_Allocate(g_audioByteBufferSize * HAE_LINUX_FRAMES_PER_BLOCK); if (g_audioBufferBlock) { g_waveDevice = HAE_OpenSoundCard(0); // for playback if (g_waveDevice > 0) { /* for linux it's * set sample format, * set channels (mono or stereo) * set sample rate */ int format = AFMT_MU_LAW; int stereo = (channels == 2); int speed = sampleRate; switch (bits) { case 8: format = AFMT_MU_LAW; /* [sbb fix] don't know if this is right or not -- maybe should be s8? */ break; case 16: format = LINUX_FORMAT16; break; //default: //fprintf(stderr, "Warning: unhandled number of data bits %d\n", (int) bits); } error = ioctl(g_waveDevice, SNDCTL_DSP_SETFMT, &format); if (error < 0) { //perror("SNDCTL_DSP_SETFMT"); //exit(1); } error = ioctl(g_waveDevice, SNDCTL_DSP_STEREO, &stereo); if (error < 0) { /* [sbb fix] issue some kind of error message */ //perror("SNDCTL_DSP_STEREO"); //exit(1); } if (ioctl(g_waveDevice, SNDCTL_DSP_SPEED, &speed) < 0) { /* Fatal error */ /* [sbb fix] handle this better */ //perror("SNDCTL_DSP_SPEED"); // $$ay: dont exit ! // exit(1); } if (speed != (INT32) sampleRate) { /* [sbb fix] need to issue a message */ } if (error == 0) { g_shutDownDoubleBuffer = FALSE; g_activeDoubleBuffer = TRUE; /* must enable process, before thread begins */ /* $$kk: 05.06.98: added this whole block. * we need to reset the lastPos each time the device gets acquired. * otherwise we may get stuck in the wait loop because we never count * up to the right sample position. */ { #ifdef NOT_HERE_BUT_PRESERVED audio_info_t sunAudioHeader; long sampleFrameSize; ioctl(g_waveDevice, AUDIO_GETINFO, &sunAudioHeader); /* [sbb] I don't think this should be any value other than zero, * since we just opened the device... */ /* lastPos = sunAudioHeader.play.samples - ((g_audioByteBufferSize * HAE_LINUX_FRAMES_PER_BLOCK * 2) / sampleFrameSize); */ lastPos = 0; #endif } /* Spin threads for device service and possibly * stream service. */ /* create thread to manage and render audio frames */ error = HAE_CreateFrameThread(context, PV_AudioWaveOutFrameThread); if (error == 0) { /* ok */ flag = 0; } else { flag = 1; g_activeDoubleBuffer = FALSE; } } } } if (flag) { /* something failed */ HAE_CloseSoundCard(0); // Close for playback } return flag; }
// Aquire and enabled audio card // return 0 if ok, -1 if failed // $$fb 2002-02-01: itanium port int HAE_AquireAudioCapture(void *context, UINT32 encoding, UINT32 sampleRate, UINT32 channels, UINT32 bits, UINT32 audioFramesPerBuffer, UINT_PTR *pCaptureHandle) { long error = -1; //long minFramesPerBuffer; g_encoding = encoding; g_bitSize = bits; g_channels = channels; g_sampleRate = sampleRate; // $$jb: 05.19.99: Setting the buffer size // $$kk: 08.06.99: i got rid of the fixed minimum value for buffersize // minFramesPerBuffer = sampleRate * HAE_LINUX_MIN_BUFFERSIZE_IN_MS / 1000; if ( audioFramesPerBuffer == 0 ) { audioFramesPerBuffer = sampleRate * HAE_LINUX_DEFAULT_BUFFERSIZE_IN_MS / 1000; } // $$kk: 08.06.99: got rid of fixed minimum buffer size /* if ( audioFramesPerBuffer >= minFramesPerBuffer ) { g_audioFramesToRead = audioFramesPerBuffer; } else { g_audioFramesToRead = minFramesPerBuffer; } */ g_audioFramesToRead = audioFramesPerBuffer / g_audioCaptureBufferSizeDivisor; if (pCaptureHandle) { *pCaptureHandle = 0L; } // try to open wave device for recording // $$kk: 12.17.97: need O_NONBLOCK flag to be compatible with windows // $$kk: 10.13.98: we want O_NONBLOCK so that we return failure immediately if the // device is busy (or absent or whatever) rather than blocking. however, i think that // this same O_NONBLOCK flag dictates whether the read() calls should block. even // without the O_NONBLOCK flag set, read() does *not* block for me, so i'm keeping // the flag for now.... HAE_OpenSoundCard(1); // Open for capture if (g_waveDevice > 0) { int format = AFMT_MU_LAW; int stereo = (channels == 2); int speed = sampleRate; switch (bits) { case 8: format = AFMT_MU_LAW; /* [sbb fix] don't know if this is right or not -- maybe should be s8? */ break; case 16: format = AFMT_S16_LE; /* [sbb fix] needs to be conditional? */ break; //default: // fprintf(stderr, "Warning: unhandled number of data bits %d\n", (int) bits); } error = ioctl(g_waveDevice, SNDCTL_DSP_SETFMT, &format); if (error < 0) { //perror("SNDCTL_DSP_SETFMT"); //exit(1); } error = ioctl(g_waveDevice, SNDCTL_DSP_STEREO, &stereo); if (error < 0) { /* [sbb fix] issue some kind of error message */ //perror("SNDCTL_DSP_STEREO"); //exit(1); } if (ioctl(g_waveDevice, SNDCTL_DSP_SPEED, &speed) < 0) { /* Fatal error */ /* [sbb fix] handle this better */ //perror("SNDCTL_DSP_SPEED"); // $$ay: dont exit ! // exit(1); } if (speed != (INT32) sampleRate) { /* [sbb fix] need to issue a message */ } if (error == 0) { // flush anything we might have accumulated in the capture queue before pausing HAE_FlushAudioCapture(); error = ioctl(g_waveDevice, SNDCTL_DSP_GETBLKSIZE, &g_audioFramesToRead); g_audioFramesToRead = g_audioFramesToRead / (channels * bits / 8); if (error == 0) { if (pCaptureHandle) { *pCaptureHandle = (UINT_PTR)g_waveDevice; } } } } if (error != 0) { // something failed HAE_ReleaseAudioCapture(context); } return (error == 0 ? 0 : -1); }