📄 audriv_mme.c
字号:
printf("Formats supported: 0x%x\n", wave_out_caps->dwFormats); printf("number of sources supported: 0x%x\n", wave_out_caps->wChannels); printf("functionality supported by driver: 0x%x\n", wave_out_caps->dwSupport);#endif mmeProcessCallbacks(); return True;}void audriv_play_close(void)/* 遍琳脱にオ〖プンされた audio を誓じますˉすでに誓じている * 眷圭はなにも乖いませんˉ */{ if(!IS_AUDIO_PLAY_OPEN) return; waveOutClose(play_wave_format->hWave); mmeProcessCallbacks(); play_wave_format->hWave = AUDIO_CLOSE_ID;}static long calculate_play_samples(void){ double es; if(play_counter <= 0) return 0; es = (double)(play_wave_format->format.wf.nSamplesPerSec * play_wave_format->format.wf.nBlockAlign) * (get_current_calender_time() - play_start_time); if(es > play_counter) return play_counter / play_wave_format->format.wf.nBlockAlign; return (long)(es / play_wave_format->format.wf.nBlockAlign);}long audriv_play_stop(void)/* 遍琳を篓郝に匿贿し·匿贿木涟のサンプル眶を手しますˉ * audriv_play_stop() の钙び叫しによって·audio は誓じますˉ * audio が贷に誓じている眷圭に audriv_play_stop() を钙び叫した眷圭は 0 を * 手しますˉ * エラ〖の眷圭は -1 を手しますˉ */{ MMRESULT status; if(!IS_AUDIO_PLAY_OPEN) return 0; status = waveOutReset(play_wave_format->hWave); if(status != MMSYSERR_NOERROR) { audriv_err(mme_error_code_string(status)); return -1; } waveOutClose(play_wave_format->hWave); mmeProcessCallbacks(); play_wave_format->hWave = AUDIO_CLOSE_ID; return calculate_play_samples();}Bool audriv_is_play_open(void)/* audio が遍琳でオ〖プンされている眷圭は True, * 誓じている眷圭は False を手しますˉ */{ return IS_AUDIO_PLAY_OPEN;}Bool audriv_set_play_volume(int volume)/* 遍琳不翁を 0 × 255 の认跋柒で肋年しますˉ0 は痰不·255 は呵络不翁ˉ * 0 踏塔は 0·255 を亩える猛は 255 に霹擦ˉ * 喇根した眷圭は True を·己窃した眷圭は False を手しますˉ */{ unsigned short left, right; DWORD vol; MMRESULT status; if(volume < 0) volume = 0; else if(volume > 255) volume = 255; left = right = ((unsigned)volume) * 257; vol = ((DWORD)left | (((DWORD)right) << 16)); status = waveOutSetVolume(play_wave_format->DevID, vol); if(status != MMSYSERR_NOERROR) { audriv_err(mme_error_code_string(status)); return False; } return True;}int audriv_get_play_volume(void)/* 遍琳不翁を 0 × 255 柒で评ますˉ0 は痰不·255 は呵络不翁ˉ * 己窃すると -1 を手し·そうでない眷圭は 0 × 255 柒の不翁を手しますˉ */{ MMRESULT status; unsigned short left, right; status = waveOutGetVolume(play_wave_format->DevID, lpdword_buff); if(status != MMSYSERR_NOERROR) { audriv_err(mme_error_code_string(status)); return -1; } left = (*lpdword_buff & 0xffff) / 257; right = ((UINT)*lpdword_buff >> 16) / 257; return (int)((left + right) / 2);}/* FIXME */Bool audriv_set_play_output(int port)/* audio の叫蜗黎 port を回年しますˉport には笆布のどれかを回年しますˉ * * AUDRIV_OUTPUT_SPEAKER スピ〖カに叫蜗ˉ * AUDRIV_OUTPUT_HEADPHONE ヘッドホンに叫蜗ˉ * AUDRIV_OUTPUT_LINE_OUT ラインアウトに叫蜗ˉ * * 喇根した眷圭は True を·己窃した眷圭は False を手しますˉ */{ switch(port) { case AUDRIV_OUTPUT_SPEAKER: case AUDRIV_OUTPUT_HEADPHONE: case AUDRIV_OUTPUT_LINE_OUT: output_port = port; break; default: audriv_err("回年嘲の叫蜗ポ〖トが回年されましたˉ"); return False; } return True;}/* FIXME */int audriv_get_play_output(void)/* audio の叫蜗黎 port を评ますˉ * 己窃すると -1 を手し·喇根すると笆布のいずれかの猛を手しますˉ * * AUDRIV_OUTPUT_SPEAKER スピ〖カに叫蜗ˉ * AUDRIV_OUTPUT_HEADPHONE ヘッドホンに叫蜗ˉ * AUDRIV_OUTPUT_LINE_OUT ラインアウトに叫蜗ˉ * */{ return output_port;}int audriv_write(char *buff, int n)/* audio に buff を n バイト尸萎し哈みますˉ * audriv_set_noblock_write() で润ブロックˇモ〖ドが肋年された * 眷圭は·この簇眶の钙び叫しは篓郝に借妄が手りますˉ * 手り猛は悸狠に萎し哈まれたバイト眶であり·润ブロックˇモ〖ドが肋年 * されている眷圭は·苞眶 n より警ない眷圭がありますˉ * 己窃すると -1 を手し·喇根すると·悸狠に萎し哈まれたバイト眶を手しますˉ */{ struct data_block_t *block; int len, total, loop_cnt; MMRESULT status; total = 0; loop_cnt = 0; while(n > 0) { mmeProcessCallbacks(); if((block = new_data_block()) == NULL) { if(audio_write_noblocking) return total; mmeWaitForCallbacks (); /* block so we don't hog 100% of the CPU */ continue; } block->in_use = AUDRIV_WRITE; if(n <= DATA_BLOCK_SIZE) len = n; else len = DATA_BLOCK_SIZE; memcpy(block->data, buff + total, len); play_wave_format->waveHdr.dwBufferLength = len; play_wave_format->waveHdr.lpData = block->data; play_wave_format->waveHdr.dwUser = block->blockno; status = waveOutWrite(play_wave_format->hWave, &play_wave_format->waveHdr, sizeof(WAVEHDR)); if(status != MMSYSERR_NOERROR) { audriv_err(mme_error_code_string(status)); return -1; } if(audriv_play_active() == 0) { reset_samples += play_counter / play_wave_format->format.wf.nBlockAlign; play_counter = 0; } if(play_counter == 0) play_start_time = get_current_calender_time(); play_counter += len; total += len; n -= len; loop_cnt++; if(audio_write_noblocking && loop_cnt >= DATA_BLOCK_NUM/2) break; } return total;}Bool audriv_set_noblock_write(Bool noblock)/* noblock に True を回年すると·audriv_write() 钙び叫しでブロックしませんˉ * False を回年すると·デフォルトの觉轮に提しますˉ * 借妄に喇根すると True を·己窃すると False を手しますˉ */{ audio_write_noblocking = noblock; return True;}int audriv_play_active(void)/* 遍琳面なら 1·遍琳面でないなら 0, エラ〖なら -1 を手しますˉ */{ double es; if(play_counter <= 0) return 0; es = (double)(play_wave_format->format.wf.nSamplesPerSec * play_wave_format->format.wf.nBlockAlign) * (get_current_calender_time() - play_start_time); if(es > play_counter) return 0; return 1;}long audriv_play_samples(void)/* 附哼遍琳面のサンプル疤弥を手しますˉ */{#if 1 /* audriv_play_samples() */ return reset_samples + calculate_play_samples();#else MMRESULT status; int sample; wave_time_info->wType = TIME_SAMPLES; status = waveOutGetPosition(play_wave_format->hWave, wave_time_info, sizeof(MMTIME)); if(status != MMSYSERR_NOERROR) { audriv_err(mme_error_code_string(status)); return -1; } sample = (int)wave_time_info->u.sample; if(sample < 0) return 0; return (long)sample;#endif}long audriv_get_filled(void)/* オ〖ディオバッファ柒のバイト眶を手します。 * エラ〖の眷圭は -1 を手します。 */{ double es; if(play_counter <= 0) return 0; es = (double)(play_wave_format->format.wf.nSamplesPerSec * play_wave_format->format.wf.nBlockAlign) * (get_current_calender_time() - play_start_time); if(es > play_counter) return 0; return play_counter - (long)es;}const long *audriv_available_encodings(int *n_ret)/* マシンがサポ〖トしているすべての射规步リストを手しますˉn_ret には * その硷梧の眶が·手されますˉ射规步をあらわす年眶猛は * aenc.h 柒に年盗されている enum audio_encoding_types の猛ですˉ * 手り猛は free してはなりませんˉ */{ static const long encoding_list[] = { AENC_UNSIGBYTE, /* WAVE_FORMAT_PCM */ AENC_G711_ULAW, /* WAVE_FORMAT_MULAW */ AENC_SIGWORDL, /* WAVE_FORMAT_PCM */ }; *n_ret = 3; return encoding_list;}const long *audriv_available_sample_rates(int *n_ret)/* マシンがサポ〖トしているすべてのサンプルレ〖トのリストを手しますˉ * n_ret にはその硷梧の眶が·手されますˉ * 手り猛は free してはなりませんˉ */{ static const long sample_rates[] = { 5512, 6615, 8000, 9600, 11025, 16000, 18900, 22050, 32000, 37800, 44100, 48000 }; *n_ret = 12; return sample_rates;}const long *audriv_available_channels(int *n_ret)/* マシンがサポ〖トしているすべてのチャネル眶のリストを手しますˉ * n_ret にはその硷梧の眶が·手されますˉ * 手り猛は free してはなりませんˉ */{ static const long channels[] = {1, 2}; *n_ret = 2; return channels;}static void set_wave_format_encoding(PCMWAVEFORMAT *format, long encoding){ switch(encoding) { case AENC_UNSIGBYTE: format->wf.wFormatTag = WAVE_FORMAT_PCM; format->wBitsPerSample = 8; break; case AENC_G711_ULAW: format->wf.wFormatTag = WAVE_FORMAT_MULAW; format->wBitsPerSample = 8; break; case AENC_G711_ALAW: format->wf.wFormatTag = WAVE_FORMAT_ALAW; format->wBitsPerSample = 8; break; case AENC_SIGWORDL: format->wf.wFormatTag = WAVE_FORMAT_PCM; format->wBitsPerSample = 16; break; case AENC_UNSIGWORDL: format->wf.wFormatTag = WAVE_FORMAT_PCM; format->wBitsPerSample = 16; break; } format->wf.nBlockAlign = format->wf.nChannels * (format->wBitsPerSample / 8);}Bool audriv_set_play_encoding(long encoding)/* audio 遍琳箕の射规步数及を回年しますˉ * 喇根した眷圭は True を·己窃した眷圭は False を手しますˉ */{ int i, n; const long *enc; enc = audriv_available_encodings(&n); for(i = 0; i < n; i++) if(enc[i] == encoding) { set_wave_format_encoding(&play_wave_format->format, encoding); return True; } return False;}Bool audriv_set_play_sample_rate(long sample_rate)/* audio 遍琳箕のサンプルレ〖トを回年しますˉ * 喇根した眷圭は True を·己窃した眷圭は False を手しますˉ */{ int i, n; const long *r; r = audriv_available_sample_rates(&n); for(i = 0; i < n; i++) if(r[i] == sample_rate) { play_wave_format->format.wf.nSamplesPerSec = sample_rate; play_wave_format->format.wf.nAvgBytesPerSec = play_wave_format->format.wf.nSamplesPerSec * play_wave_format->format.wf.nBlockAlign; return True; } return False;}Bool audriv_set_play_channels(long channels)/* 遍琳脱のチャネル眶を肋年しますˉ * 己窃すると False を手し·喇根すると True を手しますˉ */{ int i, n; const long *c = audriv_available_channels(&n); for(i = 0; i < n; i++) if(channels == c[i]) { play_wave_format->format.wf.nChannels = channels; play_wave_format->format.wf.nBlockAlign = channels * (play_wave_format->format.wBitsPerSample / 8); play_wave_format->format.wf.nAvgBytesPerSec = play_wave_format->format.wf.nSamplesPerSec * play_wave_format->format.wf.nBlockAlign; return True; } return False;}void audriv_wait_play(void)/* CPU パワ〖を喜锐しないようにするために·办箕弄に匿贿しますˉ*/{ mmeWaitForCallbacks();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -