|
|
nono 1.7.0
//
// nono
// Copyright (C) 2025 nono project
// Licensed under nono-license.txt
//
//
// サウンドの NetBSD audio(4) ドライバ
//
#include "sounddriver_netbsd.h"
#include "config.h"
#include "mainapp.h"
#include "sound.h"
#include <fcntl.h>
#include <unistd.h>
#include <sys/audioio.h>
#include <sys/ioctl.h>
// コンストラクタ
SoundDriverNetBSD::SoundDriverNetBSD(HostDevice *hostdev_)
: inherited(hostdev_, "netbsd")
{
}
// デストラクタ
SoundDriverNetBSD::~SoundDriverNetBSD()
{
fd.Close();
}
bool
SoundDriverNetBSD::InitDriver(bool startup)
{
if (inherited::InitDriver(startup) == false) {
return false;
}
// NetBSD audio(4) はオープンしたまま保持してても困らないので
// 生存期間中ずっとオープンしておく。
const ConfigItem& item = gConfig->Find("hostsound-netbsd-device");
device = item.AsString();
if (device.empty()) {
item.Err();
return false;
}
// device は '/'(スラッシュ) から始まっていればフルパス。
// そうでなければ "/dev/" を接頭する。
if (device[0] != '/') {
device = "/dev/" + device;
}
fd = open(device.c_str(), O_WRONLY);
if (fd < 0) {
warn("%s: open %s failed", __method__, device.c_str());
return false;
}
struct audio_info info;
AUDIO_INITINFO(&info);
info.play.sample_rate = freq;
info.play.channels = Sound::NCHAN;
info.play.precision = 16;
info.play.encoding = AUDIO_ENCODING_SLINEAR; // ホストエンディアン
if (ioctl(fd, AUDIO_SETINFO, &info) < 0) {
warn("%s: %s: AUDIO_SETINFO failed", __method__, device.c_str());
return false;
}
return true;
}
// ブロック書き出し
void
SoundDriverNetBSD::Write(const int16 *blk)
{
size_t written = 0;
for (; written < blkbytes;) {
const uint8 *buf = (const uint8 *)blk;
auto r = write(fd, buf + written, blkbytes - written);
if (r < 0) {
if (errno == EINTR) {
continue;
}
warn("%s: write failed", __method__);
return;
}
written += r;
}
}
void
SoundDriverNetBSD::MonitorScreenMD(TextScreen& screen, int y)
{
screen.Print(0, y, "Device path: %s", device.c_str());
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.