static int kai_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate) { cubeb_stream_params params; KAISPEC wanted_spec; KAISPEC spec; HKAI hkai; params.format = CUBEB_SAMPLE_S16NE; params.rate = 48000; params.channels = 2; wanted_spec.usDeviceIndex = 0; wanted_spec.ulType = KAIT_PLAY; wanted_spec.ulBitsPerSample = BPS_16; wanted_spec.ulSamplingRate = params.rate; wanted_spec.ulDataFormat = MCI_WAVE_FORMAT_PCM; wanted_spec.ulChannels = params.channels; wanted_spec.ulNumBuffers = NBUFS; wanted_spec.ulBufferSize = frames_to_bytes(FRAME_SIZE, params); wanted_spec.fShareable = TRUE; wanted_spec.pfnCallBack = kai_callback; wanted_spec.pCallBackData = NULL; /* Test 48KHz */ if (kaiOpen(&wanted_spec, &spec, &hkai)) { /* Not supported. Fall back to 44.1KHz */ params.rate = 44100; } else { /* Supported. Use 48KHz */ kaiClose(hkai); } *rate = params.rate; return CUBEB_OK; }
void playThread( void *arg ) { char *name = arg; HMMIO hmmio; MMIOINFO mmioInfo; MMAUDIOHEADER mmAudioHeader; LONG lBytesRead; KAISPEC ksWanted, ksObtained; HKAI hkai; CBDATA cd; /* Open the audio file. */ memset( &mmioInfo, '\0', sizeof( MMIOINFO )); mmioInfo.fccIOProc = mmioFOURCC('W', 'A', 'V', 'E'); hmmio = mmioOpen( name, &mmioInfo, MMIO_READ | MMIO_DENYNONE ); if( !hmmio ) { fprintf( stderr, "[%s] Failed to open a wave file!!!\n", name ); goto exit_discount_threads; } /* Get the audio file header. */ mmioGetHeader( hmmio, &mmAudioHeader, sizeof( MMAUDIOHEADER ), &lBytesRead, 0, 0); memset( &cd, 0, sizeof( CBDATA )); cd.hmmio = hmmio; ksWanted.usDeviceIndex = 0; ksWanted.ulType = KAIT_PLAY; ksWanted.ulBitsPerSample = mmAudioHeader.mmXWAVHeader.WAVEHeader.usBitsPerSample; ksWanted.ulSamplingRate = mmAudioHeader.mmXWAVHeader.WAVEHeader.ulSamplesPerSec; ksWanted.ulDataFormat = 0; ksWanted.ulChannels = mmAudioHeader.mmXWAVHeader.WAVEHeader.usChannels; ksWanted.ulNumBuffers = 2; ksWanted.ulBufferSize = 0; ksWanted.fShareable = TRUE; ksWanted.pfnCallBack = kaiCallback; ksWanted.pCallBackData = &cd; if( kaiOpen( &ksWanted, &ksObtained, &hkai )) { fprintf( stderr, "[%s] Failed to open audio device!!!\n", name ); goto exit_mmio_close; } printf("[%s] hkai = %lx\n", name, hkai ); kaiSetVolume( hkai, MCI_SET_AUDIO_ALL, 50 ); kaiSetSoundState( hkai, MCI_SET_AUDIO_ALL, TRUE ); printf("[%s] Trying to play...\n", name ); //DosSetPriority( PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, 0 ); while( 1 ) { switch( kaiPlay( hkai )) { case KAIE_NO_ERROR : break; #if 0 // Wait for instance to be active case KAIE_NOT_READY : DosSleep( 1 ); continue; #endif default : fprintf( stderr, "[%s] Failed to play!!!\n", name ); goto exit_kai_close; } break; } //DosSetPriority( PRTYS_THREAD, PRTYC_REGULAR, 0, 0 ); printf("[%s] Playing...\n", name ); while( !m_fQuit && !( kaiStatus( hkai ) & KAIS_COMPLETED )) DosSleep( 1 ); printf("[%s] Completed\n", name ); exit_kai_close : kaiClose( hkai ); exit_mmio_close : mmioClose( hmmio, 0 ); exit_discount_threads : m_nThreads--; }
/***************************************************************************** * Open: open the audio device *****************************************************************************/ static int Start ( audio_output_t *p_aout, audio_sample_format_t *fmt ) { aout_sys_t *p_sys = p_aout->sys; char *psz_mode; ULONG i_kai_mode; KAISPEC ks_wanted, ks_obtained; int i_nb_channels; int i_bytes_per_frame; vlc_value_t val, text; audio_sample_format_t format = *fmt; if( var_Get( p_aout, "audio-device", &val ) != VLC_ENOVAR ) { /* The user has selected an audio device. */ if ( val.i_int == AOUT_VAR_STEREO ) { format.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; } else if ( val.i_int == AOUT_VAR_MONO ) { format.i_physical_channels = AOUT_CHAN_CENTER; } } psz_mode = var_InheritString( p_aout, "kai-audio-device" ); if( !psz_mode ) psz_mode = ( char * )ppsz_kai_audio_device[ 0 ]; // "auto" i_kai_mode = KAIM_AUTO; if( strcmp( psz_mode, "dart" ) == 0 ) i_kai_mode = KAIM_DART; else if( strcmp( psz_mode, "uniaud" ) == 0 ) i_kai_mode = KAIM_UNIAUD; msg_Dbg( p_aout, "selected mode = %s", psz_mode ); if( psz_mode != ppsz_kai_audio_device[ 0 ]) free( psz_mode ); i_nb_channels = aout_FormatNbChannels( &format ); if ( i_nb_channels > 2 ) { /* KAI doesn't support more than two channels. */ i_nb_channels = 2; format.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; } /* Support s16l only */ format.i_format = VLC_CODEC_S16L; aout_FormatPrepare( &format ); i_bytes_per_frame = format.i_bytes_per_frame; /* Initialize library */ if( kaiInit( i_kai_mode )) { msg_Err( p_aout, "cannot initialize KAI"); return VLC_EGENERIC; } ks_wanted.usDeviceIndex = 0; ks_wanted.ulType = KAIT_PLAY; ks_wanted.ulBitsPerSample = BPS_16; ks_wanted.ulSamplingRate = format.i_rate; ks_wanted.ulDataFormat = MCI_WAVE_FORMAT_PCM; ks_wanted.ulChannels = i_nb_channels; ks_wanted.ulNumBuffers = 2; ks_wanted.ulBufferSize = FRAME_SIZE * i_bytes_per_frame; ks_wanted.fShareable = !var_InheritBool( p_aout, "kai-audio-exclusive-mode"); ks_wanted.pfnCallBack = KaiCallback; ks_wanted.pCallBackData = p_aout; msg_Dbg( p_aout, "requested ulBufferSize = %ld", ks_wanted.ulBufferSize ); /* Open the sound device. */ if( kaiOpen( &ks_wanted, &ks_obtained, &p_sys->hkai )) { msg_Err( p_aout, "cannot open KAI device"); goto exit_kai_done; } msg_Dbg( p_aout, "open in %s mode", ks_obtained.fShareable ? "shareable" : "exclusive" ); msg_Dbg( p_aout, "obtained i_nb_samples = %lu", ks_obtained.ulBufferSize / i_bytes_per_frame ); msg_Dbg( p_aout, "obtained i_bytes_per_frame = %d", format.i_bytes_per_frame ); p_sys->format = *fmt = format; p_aout->time_get = aout_PacketTimeGet; p_aout->play = Play; p_aout->pause = NULL; p_aout->flush = aout_PacketFlush; aout_SoftVolumeStart( p_aout ); aout_PacketInit( p_aout, &p_sys->packet, ks_obtained.ulBufferSize / i_bytes_per_frame, &format ); if ( var_Type( p_aout, "audio-device" ) == 0 ) { /* First launch. */ var_Create( p_aout, "audio-device", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE ); text.psz_string = _("Audio Device"); var_Change( p_aout, "audio-device", VLC_VAR_SETTEXT, &text, NULL ); val.i_int = AOUT_VAR_STEREO; text.psz_string = _("Stereo"); var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text ); val.i_int = AOUT_VAR_MONO; text.psz_string = _("Mono"); var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text ); if ( i_nb_channels == 2 ) { val.i_int = AOUT_VAR_STEREO; } else { val.i_int = AOUT_VAR_MONO; } var_Change( p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val, NULL ); var_AddCallback( p_aout, "audio-device", aout_ChannelsRestart, NULL ); } /* Prevent SIG_FPE */ _control87(MCW_EM, MCW_EM); return VLC_SUCCESS; exit_kai_done : kaiDone(); return VLC_EGENERIC; }
static int kai_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name, cubeb_devid input_device, cubeb_stream_params * input_stream_params, cubeb_devid output_device, cubeb_stream_params * output_stream_params, unsigned int latency, cubeb_data_callback data_callback, cubeb_state_callback state_callback, void * user_ptr) { cubeb_stream * stm; KAISPEC wanted_spec; XASSERT(!input_stream_params && "not supported."); if (input_device || output_device) { /* Device selection not yet implemented. */ return CUBEB_ERROR_DEVICE_UNAVAILABLE; } if (!output_stream_params) return CUBEB_ERROR_INVALID_PARAMETER; if (output_stream_params->channels < 1 || output_stream_params->channels > MAX_CHANNELS) return CUBEB_ERROR_INVALID_FORMAT; XASSERT(context); XASSERT(stream); *stream = NULL; stm = calloc(1, sizeof(*stm)); XASSERT(stm); stm->context = context; stm->params = *output_stream_params; stm->data_callback = data_callback; stm->state_callback = state_callback; stm->user_ptr = user_ptr; stm->soft_volume = -1.0f; if (_fmutex_create(&stm->mutex, 0)) { free(stm); return CUBEB_ERROR; } wanted_spec.usDeviceIndex = 0; wanted_spec.ulType = KAIT_PLAY; wanted_spec.ulBitsPerSample = BPS_16; wanted_spec.ulSamplingRate = stm->params.rate; wanted_spec.ulDataFormat = MCI_WAVE_FORMAT_PCM; wanted_spec.ulChannels = stm->params.channels; wanted_spec.ulNumBuffers = NBUFS; wanted_spec.ulBufferSize = frames_to_bytes(FRAME_SIZE, stm->params); wanted_spec.fShareable = TRUE; wanted_spec.pfnCallBack = kai_callback; wanted_spec.pCallBackData = stm; if (kaiOpen(&wanted_spec, &stm->spec, &stm->hkai)) { _fmutex_close(&stm->mutex); free(stm); return CUBEB_ERROR; } *stream = stm; return CUBEB_OK; }
/***************************************************************************** * Open: open the audio device *****************************************************************************/ static int Start ( audio_output_t *p_aout, audio_sample_format_t *fmt ) { aout_sys_t *p_sys = p_aout->sys; char *psz_mode; ULONG i_kai_mode; KAISPEC ks_wanted, ks_obtained; int i_nb_channels; int i_bytes_per_frame; vlc_value_t val, text; audio_sample_format_t format = *fmt; psz_mode = var_InheritString( p_aout, "kai-audio-device" ); if( !psz_mode ) psz_mode = ( char * )ppsz_kai_audio_device[ 0 ]; // "auto" i_kai_mode = KAIM_AUTO; if( strcmp( psz_mode, "dart" ) == 0 ) i_kai_mode = KAIM_DART; else if( strcmp( psz_mode, "uniaud" ) == 0 ) i_kai_mode = KAIM_UNIAUD; msg_Dbg( p_aout, "selected mode = %s", psz_mode ); if( psz_mode != ppsz_kai_audio_device[ 0 ]) free( psz_mode ); i_nb_channels = aout_FormatNbChannels( &format ); if ( i_nb_channels >= 2 ) { /* KAI doesn't support more than two channels. */ i_nb_channels = 2; format.i_physical_channels = AOUT_CHANS_STEREO; } else format.i_physical_channels = AOUT_CHAN_CENTER; /* Support S16 only */ format.i_format = VLC_CODEC_S16N; aout_FormatPrepare( &format ); i_bytes_per_frame = format.i_bytes_per_frame; /* Initialize library */ if( kaiInit( i_kai_mode )) { msg_Err( p_aout, "cannot initialize KAI"); return VLC_EGENERIC; } ks_wanted.usDeviceIndex = 0; ks_wanted.ulType = KAIT_PLAY; ks_wanted.ulBitsPerSample = BPS_16; ks_wanted.ulSamplingRate = format.i_rate; ks_wanted.ulDataFormat = MCI_WAVE_FORMAT_PCM; ks_wanted.ulChannels = i_nb_channels; ks_wanted.ulNumBuffers = 2; ks_wanted.ulBufferSize = FRAME_SIZE * i_bytes_per_frame; ks_wanted.fShareable = !var_InheritBool( p_aout, "kai-audio-exclusive-mode"); ks_wanted.pfnCallBack = KaiCallback; ks_wanted.pCallBackData = p_aout; msg_Dbg( p_aout, "requested ulBufferSize = %ld", ks_wanted.ulBufferSize ); /* Open the sound device. */ if( kaiOpen( &ks_wanted, &ks_obtained, &p_sys->hkai )) { msg_Err( p_aout, "cannot open KAI device"); goto exit_kai_done; } msg_Dbg( p_aout, "open in %s mode", ks_obtained.fShareable ? "shareable" : "exclusive" ); msg_Dbg( p_aout, "obtained i_nb_samples = %lu", ks_obtained.ulBufferSize / i_bytes_per_frame ); msg_Dbg( p_aout, "obtained i_bytes_per_frame = %d", format.i_bytes_per_frame ); p_sys->format = *fmt = format; p_aout->time_get = TimeGet; p_aout->play = Play; p_aout->pause = Pause; p_aout->flush = Flush; aout_SoftVolumeStart( p_aout ); CreateBuffer( p_aout, AUDIO_BUFFER_SIZE_IN_SECONDS * format.i_rate * format.i_bytes_per_frame ); /* Prevent SIG_FPE */ _control87(MCW_EM, MCW_EM); return VLC_SUCCESS; exit_kai_done : kaiDone(); return VLC_EGENERIC; }