|
|
nono 1.7.0
//
// nono
// Copyright (C) 2025 nono project
// Licensed under nono-license.txt
//
//
// サウンドの ALSA ドライバ
//
#include "sounddriver_alsa.h"
#include "config.h"
#include "mainapp.h"
#include "sound.h"
#include <alsa/asoundlib.h>
// コンストラクタ
SoundDriverALSA::SoundDriverALSA(HostDevice *hostdev_)
: inherited(hostdev_, "alsa")
{
}
// デストラクタ
SoundDriverALSA::~SoundDriverALSA()
{
Close();
}
bool
SoundDriverALSA::InitDriver(bool startup)
{
snd_pcm_hw_params_t *params;
bool rv = false;
if (inherited::InitDriver(startup) == false) {
return false;
}
const ConfigItem& item = gConfig->Find("hostsound-alsa-device");
device = item.AsString();
if (snd_pcm_open(&pcm, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0) < 0) {
warnx("%s: snd_pcm_open(%s) failed", __method__, device.c_str());
return false;
}
uint period = freq * Sound::BLK_TSEC / 1_sec;
snd_pcm_hw_params_malloc(¶ms);
snd_pcm_hw_params_any(pcm, params);
snd_pcm_hw_params_set_format(pcm, params, SND_PCM_FORMAT_S16);//HostEndian
snd_pcm_hw_params_set_access(pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_hw_params_set_channels(pcm, params, Sound::NCHAN);
snd_pcm_hw_params_set_rate(pcm, params, freq, 0);
snd_pcm_hw_params_set_period_size(pcm, params, period, 0);
snd_pcm_hw_params_set_buffer_size(pcm, params, period * 4);
if (snd_pcm_hw_params(pcm, params) < 0) {
warnx("%s: snd_pcm_hw_params() failed", __method__);
goto done;
}
rv = true;
done:
snd_pcm_hw_params_free(params);
return rv;
}
// ブロック書き出し
void
SoundDriverALSA::Write(const int16 *blk)
{
size_t frames_per_blk = blkbytes / Sound::FRAME_BYTES;
// ALSA では書き込みはフレーム単位で、一度に行う志向。
snd_pcm_prepare(pcm);
auto r = snd_pcm_writei(pcm, blk, frames_per_blk);
if (r < 0) {
warnx("%s: snd_pcm_writei() failed: %d", __method__, (int)r);
snd_pcm_prepare(pcm);
if (r == -EPIPE) {
// 一度だけ再試行してみる?
snd_pcm_writei(pcm, blk, frames_per_blk);
}
}
}
void
SoundDriverALSA::Close()
{
snd_pcm_drain(pcm);
snd_pcm_close(pcm);
}
void
SoundDriverALSA::MonitorScreenMD(TextScreen& screen, int y)
{
screen.Print(0, y, "Device: %s", device.c_str());
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.