// Given the capture hardware is working, fill a buffer with some data. This call is // asynchronous. When this buffer is filled, the function done will be called. // returns 0 for success, -1 for failure int HAE_StartAudioCapture(HAE_CaptureDone done, void *callbackContext) { long error = -1; //fprintf(stderr, ">> HAE_API_LinuxOS_Capture: HAE_StartAudioCapture()\n"); if (g_waveDevice && g_openForCapture) { // start capture g_captureDoneProc = done; // allocate the capture buffer // $$jb: 05.19.99: This is set in HAE_AquireAudioCapture //g_audioFramesToRead = HAE_LINUX_FRAMES_PER_BUFFER; // our read buffer will hold this many frames of sampled audio data // we're going to build this many buffers at a time if (g_bitSize == 8) { g_captureByteBufferSize = (sizeof(char) * g_audioFramesToRead); } else { g_captureByteBufferSize = (sizeof(short int) * g_audioFramesToRead); } g_captureByteBufferSize *= g_channels; // allocate read buffer g_captureBufferBlock = HAE_Allocate(g_captureByteBufferSize); if (g_captureBufferBlock) { // $$kk: 10.12.98: added this so we can restart capture // $$kk: 11.03.98: mark ourselves active *before* creating frame thread g_captureShutdown = FALSE; // create thread to manage audio capture error = HAE_CreateFrameThread(callbackContext, PV_AudioWaveInFrameThread); if (error == 0) { error = HAE_ResumeAudioCapture(); } } if (error != 0) { g_captureShutdown = TRUE; } } //fprintf(stderr, "<< HAE_API_LinuxOS_Capture: HAE_StartAudioCapture() returning %d\n", error); return (error == 0) ? 0 : -1; }
// Given the capture hardware is working, fill a buffer with some data. This call is // asynchronous. When this buffer is filled, the function done will be called. // returns 0 for success, -1 for failure int HAE_StartAudioCapture(HAE_CaptureDone done, void *callbackContext) { long error = 0; int i; // start capture g_captureDoneProc = done; g_captureDoneContext = callbackContext; // calculate the number of bytes per capture buffer if (g_bitSize == 8) { g_audioBytesPerBuffer = (sizeof(char) * g_audioFramesPerBuffer); } else { g_audioBytesPerBuffer = (sizeof(short int) * g_audioFramesPerBuffer); } g_audioBytesPerBuffer *= g_channels; // allocate the capture data buffers // this could really be done in initialiation...? for (i = 0; i < HAE_WAVEIN_NUM_BUFFERS; i++) { g_audioBufferBlock[i] = HAE_Allocate(g_audioBytesPerBuffer); if (g_audioBufferBlock[i] == NULL) { error = -1; // something is wrong break; } } // for if (error == 0) { // create thread to manage audio capture error = HAE_CreateFrameThread(callbackContext, PV_AudioWaveInFrameThread); if (error == 0) { error = HAE_ResumeAudioCapture(); } } if (error == 0) { // $$kk: 10.12.98: added this so we can restart capture g_captureShutdown = FALSE; } return (error == 0) ? 0 : -1; }
// **** Audio card support // Aquire and enabled audio card // return 0 if ok, -1 if failed int HAE_AquireAudioCard(void *context, UINT32 sampleRate, UINT32 channels, UINT32 bits) { int flag; short int count; INT32 error; audio_info_t sunAudioHeader; char* pAudioDev = HAE_GetAudioDevPlay(g_currentDeviceID, 0); flag = 0; g_activeDoubleBuffer = FALSE; g_shutDownDoubleBuffer = TRUE; g_audioFramesToGenerate = HAE_GetMaxSamplePerSlice(); // get number of frames per sample rate slice // we're going to build this many buffers at a time g_synthFramesPerBlock = HAE_SOLARIS_FRAMES_PER_BLOCK; g_audioPeriodSleepTime = HAE_SOLARIS_SOUND_PERIOD; g_bitSize = bits; g_channels = channels; if (bits == 8) { g_audioByteBufferSize = ((INT32)sizeof(char) * g_audioFramesToGenerate); } else { g_audioByteBufferSize = ((INT32)sizeof(short int) * g_audioFramesToGenerate); } g_audioByteBufferSize *= channels; flag = 1; // allocate buffer blocks g_audioBufferBlock = HAE_Allocate(g_audioByteBufferSize * HAE_SOLARIS_FRAMES_PER_BLOCK); if (g_audioBufferBlock) { // try to open wave device // $$kk: 12.17.97: need O_NONBLOCK flag to be compatible with windows #ifdef __linux__ g_waveDevice = open(pAudioDev,O_WRONLY); #else g_waveDevice = open(pAudioDev,O_WRONLY|O_NONBLOCK); #endif if (g_waveDevice > 0) { /* set to multiple open */ if (ioctl(g_waveDevice, AUDIO_MIXER_MULTIPLE_OPEN, NULL) >= 0) { TRACE1("HAE_AquireAudioCard: %s set to multiple open\n", pAudioDev); } else { ERROR1("HAE_AquireAudioCard: ioctl AUDIO_MIXER_MULTIPLE_OPEN failed on %s!\n", pAudioDev); } AUDIO_INITINFO(&sunAudioHeader); // $$kk: 12.17.97: need AUDIO_GETINFO ioctl to get this to work on solaris x86 // add next 1 line error = ioctl(g_waveDevice, AUDIO_GETINFO, &sunAudioHeader); // $$kk: 03.16.98: not valid to call AUDIO_SETINFO ioctl with all the fields from AUDIO_GETINFO, // so let's try init'ing again.... AUDIO_INITINFO(&sunAudioHeader); // Set rendering format of the sun device. sunAudioHeader.play.sample_rate = sampleRate; sunAudioHeader.play.precision = bits; sunAudioHeader.play.channels = channels; sunAudioHeader.play.encoding = AUDIO_ENCODING_LINEAR; error = ioctl(g_waveDevice, AUDIO_SETINFO, &sunAudioHeader); if (error == 0) { g_shutDownDoubleBuffer = FALSE; g_activeDoubleBuffer = TRUE; // must enable process, before thread begins /* 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; #ifdef USE_RAWDATA_CHECK { char* fname = "javasound_debug_output.pcm"; debugrawfile = HAE_FileOpenForWrite(fname); } #endif } else { flag = 1; g_activeDoubleBuffer = FALSE; } } } } if (flag) { // something failed HAE_ReleaseAudioCard(context); } return flag; }
// **** 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; }