File:  [Isaki's NoNo m68k/m88k emulator] / nono / host / sounddriver_netbsd.cpp
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:06:02 2026 UTC (2 months, 3 weeks ago) by root
Branches: MAIN, Isaki
CVS tags: v027, HEAD
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());
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.