📄 audriv_al.c
字号:
#endif /* SGI_OLDAL */}int audriv_get_play_volume(void)/* 遍琳不翁を 0 × 255 柒で评ますˉ0 は痰不·255 は呵络不翁ˉ * 己窃すると -1 を手し·そうでない眷圭は 0 × 255 柒の不翁を手しますˉ */{#ifndef SGI_OLDAL ALfixed lrgain[2]; ALpv pv; double gain, l, r, min, max; int volume; int resource; min = alFixedToDouble(out_ginfo.min.ll); max = alFixedToDouble(out_ginfo.max.ll); pv.param = AL_GAIN; pv.value.ptr = lrgain; pv.sizeIn = 2; if(out == NULL) resource = AL_DEFAULT_OUTPUT; else resource = alGetResource(out); if(alGetParams(resource, &pv, 1) < 0) { audriv_err(ALERROR); return -1; } l = alFixedToDouble(lrgain[0]); r = alFixedToDouble(lrgain[1]); if(l < min) l = min; else if(l > max) l = max; if(r < min) r = min; else if(r > max) r = max; gain = (l + r) / 2; volume = (gain - min) * 256 / (max - min); if(volume < 0) volume = 0; else if(volume > 255) volume = 255; return volume;#else long gain[4]; int volume; gain[0] = AL_LEFT_SPEAKER_GAIN; gain[2] = AL_RIGHT_SPEAKER_GAIN; if(ALgetparams(AL_DEFAULT_DEVICE, gain, 4) < 0) { audriv_err(ALERROR); return -1; } volume = (gain[1] + gain[3]) / 2; if(volume < 0) volume = 0; else if(volume > 255) volume = 255; return volume;#endif /* SGI_OLDAL */}Bool audriv_set_play_output(int port)/* audio の叫蜗黎 port を回年しますˉport には笆布のどれかを回年しますˉ * * AUDRIV_OUTPUT_SPEAKER スピ〖カに叫蜗ˉ * AUDRIV_OUTPUT_HEADPHONE ヘッドホンに叫蜗ˉ * AUDRIV_OUTPUT_LINE_OUT ラインアウトに叫蜗ˉ * * 喇根した眷圭は True を·己窃した眷圭は False を手しますˉ */{ if(port != AUDRIV_OUTPUT_SPEAKER) { audriv_err("回年嘲の叫蜗ポ〖トが回年されましたˉ"); return False; } return True;}int audriv_get_play_output(void)/* audio の叫蜗黎 port を评ますˉ * 己窃すると -1 を手し·喇根すると笆布のいずれかの猛を手しますˉ * * AUDRIV_OUTPUT_SPEAKER スピ〖カに叫蜗ˉ * AUDRIV_OUTPUT_HEADPHONE ヘッドホンに叫蜗ˉ * AUDRIV_OUTPUT_LINE_OUT ラインアウトに叫蜗ˉ * */{ return AUDRIV_OUTPUT_SPEAKER;}long audriv_play_samples(void)/* 附哼遍琳面のサンプル疤弥を手しますˉ */{ double realtime, es; realtime = get_current_calender_time(); if(play_counter == 0) { play_start_time = realtime; return reset_samples; } es = play_sample_rate * (realtime - play_start_time); if(es >= play_counter) { /* out of play counter */ reset_samples += play_counter; play_counter = 0; play_start_time = realtime; return reset_samples; } if(es < 0) return 0; /* for safety */ return (int32)es + reset_samples;}static void add_sample_counter(int32 count){ audriv_play_samples(); /* update offset_samples */ play_counter += count;}int audriv_write(char *buff, int n)/* audio に buff を n バイト尸萎し哈みますˉ * audriv_set_noblock_write() で润ブロックˇモ〖ドが肋年された * 眷圭は·この簇眶の钙び叫しは篓郝に借妄が手りますˉ * 手り猛は悸狠に萎し哈まれたバイト眶であり·润ブロックˇモ〖ドが肋年 * されている眷圭は·苞眶 n より警ない眷圭がありますˉ * 己窃すると -1 を手し·喇根すると·悸狠に萎し哈まれたバイト眶を手しますˉ */{ n /= play_frame_width; if(audio_write_noblocking) { int size; size = alGetFillable(out); if(size < n) n = size; } add_sample_counter(n); if(play_encoding != AENC_G711_ULAW) { alWriteFrames(out, buff, n); return n * play_frame_width; } else { /* AENC_G711_ULAW */ int i, m, ret; short samps[BUFSIZ]; n *= play_frame_width; ret = n; while(n > 0) { m = n; if(m > BUFSIZ) m = BUFSIZ; for(i = 0; i < m; i++) samps[i] = AUDIO_U2S(buff[i]); alWriteFrames(out, samps, m / play_frame_width); buff += m; n -= m; } return ret; }}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 を手しますˉ */{ return out && alGetFilled(out) > 0;}long audriv_get_filled(void)/* オ〖ディオバッファ柒のバイト眶を手します。 * エラ〖の眷圭は -1 を手します。 */{ if(out == NULL) return 0; return (long)play_frame_width * alGetFilled(out);}const long *audriv_available_encodings(int *n_ret)/* マシンがサポ〖トしているすべての射规步リストを手しますˉn_ret には * その硷梧の眶が·手されますˉ射规步をあらわす年眶猛は * aenc.h 柒に年盗されている enum aenc_data_encoding の猛ですˉ * 手り猛は free してはなりませんˉ */{ static const long encoding_list[] = { AENC_SIGBYTE, AENC_G711_ULAW, /* Pseudo audio encoding */ AENC_SIGWORDB }; *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;}Bool audriv_set_play_encoding(long encoding)/* audio 遍琳箕の射规步数及を回年しますˉ * 喇根した眷圭は True を·己窃した眷圭は False を手しますˉ */{ int i, n; const long *enc; if(encoding == play_encoding) return True; enc = audriv_available_encodings(&n); for(i = 0; i < n; i++) if(enc[i] == encoding) break; if(i == n) return False; play_encoding = encoding; play_frame_width = AENC_SAMPW(encoding) * play_nchannels; if(out) { audriv_al_set_width(out_config, encoding); alSetConfig(out, out_config); } return True;}Bool audriv_set_play_sample_rate(long sample_rate)/* audio 遍琳箕のサンプルレ〖トを回年しますˉ * 喇根した眷圭は True を·己窃した眷圭は False を手しますˉ */{#if 0 int i, n; const long *r; r = audriv_available_sample_rates(&n); for(i = 0; i < n; i++) if(r[i] == sample_rate) break; if(i == n) return False;#endif if(sample_rate == play_sample_rate) return True; play_sample_rate = sample_rate; if(out) { if(audriv_al_set_rate(out, sample_rate) == False) { audriv_err(ALERROR); return False; } } return True;}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]) break; if(i == n) return False; if(play_nchannels == channels) return True; play_nchannels = channels; play_frame_width = AENC_SAMPW(play_encoding) * play_nchannels; if(out) { audriv_play_close(); audriv_play_open(); } return True;}void audriv_wait_play(void)/* CPU パワ〖を喜锐しないようにするために·办箕弄に匿贿しますˉ*/{ double spare; spare = (double)alGetFilled(out) / (double)play_sample_rate; if(spare < 0.1) return; usleep((unsigned long)(spare * 500000.0));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -