// **** Audio card support // Aquire and enabled audio card // return 0 if ok, -1 if failed int HAE_AquireAudioCard(void *context, unsigned long sampleRate, unsigned long channels, unsigned long bits) { int flag; long bufferSize; short int bufferTime; flag = 0; g_activeDoubleBuffer = FALSE; g_shutDownDoubleBuffer = TRUE; g_audioFramesToGenerate = HAE_GetMaxSamplePerSlice(); // get number of frames per sample rate slice g_synthFramesPerBlock = HAE_FRAMES_PER_BLOCK; bufferTime = (HAE_GetSliceTimeInMicroseconds() / 1000) * g_synthFramesPerBlock; if (bits == 8) { bufferSize = (sizeof(char) * g_audioFramesToGenerate); } else { bufferSize = (sizeof(short int) * g_audioFramesToGenerate); } bufferSize *= channels; g_audioByteBufferSize = bufferSize; // try and configure card to match our audio output g_waveDevice = R0CARD_AcquireSoundCard(sampleRate, channels, bits, bufferTime, &g_audioByteBufferSize, PV_AudioHardwareCallback); if (g_waveDevice) { g_shutDownDoubleBuffer = FALSE; g_activeDoubleBuffer = TRUE; // must enable process, before thread begins flag = 0; // ok } else { flag = -1; // failed; HAE_ReleaseAudioCard(context); } return flag; }
// **** 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; }