|
|
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:
1.1.1.2 ! root 47: uint period = freq * Sound::BLK_TSEC / 1_sec;
1.1 root 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
1.1.1.2 ! root 95: SoundDriverALSA::MonitorScreenMD(TextScreen& screen, int y)
1.1 root 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.