|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2025 nono project ! 4: // Licensed under nono-license.txt ! 5: // ! 6: ! 7: // ! 8: // サウンドの ALSA ドライバ ! 9: // ! 10: ! 11: #include "sounddriver_alsa.h" ! 12: #include "config.h" ! 13: #include "mainapp.h" ! 14: #include "sound.h" ! 15: #include <alsa/asoundlib.h> ! 16: ! 17: // コンストラクタ ! 18: SoundDriverALSA::SoundDriverALSA(HostDevice *hostdev_) ! 19: : inherited(hostdev_, "alsa") ! 20: { ! 21: } ! 22: ! 23: // デストラクタ ! 24: SoundDriverALSA::~SoundDriverALSA() ! 25: { ! 26: Close(); ! 27: } ! 28: ! 29: bool ! 30: SoundDriverALSA::InitDriver(bool startup) ! 31: { ! 32: snd_pcm_hw_params_t *params; ! 33: bool rv = false; ! 34: ! 35: if (inherited::InitDriver(startup) == false) { ! 36: return false; ! 37: } ! 38: ! 39: const ConfigItem& item = gConfig->Find("hostsound-alsa-device"); ! 40: device = item.AsString(); ! 41: ! 42: if (snd_pcm_open(&pcm, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0) < 0) { ! 43: warnx("%s: snd_pcm_open(%s) failed", __method__, device.c_str()); ! 44: return false; ! 45: } ! 46: ! 47: uint period = freq * Sound::BLK_NSEC / 1_sec; ! 48: ! 49: snd_pcm_hw_params_malloc(¶ms); ! 50: snd_pcm_hw_params_any(pcm, params); ! 51: snd_pcm_hw_params_set_format(pcm, params, SND_PCM_FORMAT_S16);//HostEndian ! 52: snd_pcm_hw_params_set_access(pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED); ! 53: snd_pcm_hw_params_set_channels(pcm, params, Sound::NCHAN); ! 54: snd_pcm_hw_params_set_rate(pcm, params, freq, 0); ! 55: snd_pcm_hw_params_set_period_size(pcm, params, period, 0); ! 56: snd_pcm_hw_params_set_buffer_size(pcm, params, period * 4); ! 57: if (snd_pcm_hw_params(pcm, params) < 0) { ! 58: warnx("%s: snd_pcm_hw_params() failed", __method__); ! 59: goto done; ! 60: } ! 61: ! 62: rv = true; ! 63: done: ! 64: snd_pcm_hw_params_free(params); ! 65: return rv; ! 66: } ! 67: ! 68: // ブロック書き出し ! 69: void ! 70: SoundDriverALSA::Write(const int16 *blk) ! 71: { ! 72: size_t frames_per_blk = blkbytes / Sound::FRAME_BYTES; ! 73: ! 74: // ALSA では書き込みはフレーム単位で、一度に行う志向。 ! 75: snd_pcm_prepare(pcm); ! 76: auto r = snd_pcm_writei(pcm, blk, frames_per_blk); ! 77: if (r < 0) { ! 78: warnx("%s: snd_pcm_writei() failed: %d", __method__, (int)r); ! 79: snd_pcm_prepare(pcm); ! 80: if (r == -EPIPE) { ! 81: // 一度だけ再試行してみる? ! 82: snd_pcm_writei(pcm, blk, frames_per_blk); ! 83: } ! 84: } ! 85: } ! 86: ! 87: void ! 88: SoundDriverALSA::Close() ! 89: { ! 90: snd_pcm_drain(pcm); ! 91: snd_pcm_close(pcm); ! 92: } ! 93: ! 94: void ! 95: SoundDriverALSA::MonitorUpdateMD(TextScreen& screen, int y) ! 96: { ! 97: screen.Print(0, y, "Device: %s", device.c_str()); ! 98: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.