66 lines
2.8 KiB
Zig
66 lines
2.8 KiB
Zig
const std = @import("std");
|
|
const sysaudio = @import("sysaudio");
|
|
|
|
var player: sysaudio.Player = undefined;
|
|
|
|
pub fn main() !void {
|
|
var timer = try std.time.Timer.start();
|
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
defer _ = gpa.deinit();
|
|
const allocator = gpa.allocator();
|
|
|
|
var ctx = try sysaudio.Context.init(null, allocator, .{ .deviceChangeFn = deviceChange });
|
|
std.log.info("Took {} to initialize the context...", .{std.fmt.fmtDuration(timer.lap())});
|
|
defer ctx.deinit();
|
|
try ctx.refresh();
|
|
std.log.info("Took {} to refresh the context...", .{std.fmt.fmtDuration(timer.lap())});
|
|
|
|
const device = ctx.defaultDevice(.playback) orelse return error.NoDevice;
|
|
std.log.info("Took {} to get the default playback device...", .{std.fmt.fmtDuration(timer.lap())});
|
|
|
|
player = try ctx.createPlayer(device, writeCallback, .{});
|
|
std.log.info("Took {} to create a player...", .{std.fmt.fmtDuration(timer.lap())});
|
|
defer player.deinit();
|
|
try player.start();
|
|
std.log.info("Took {} to start the player...", .{std.fmt.fmtDuration(timer.lap())});
|
|
|
|
try player.setVolume(0.85);
|
|
std.log.info("Took {} to set the volume...", .{std.fmt.fmtDuration(timer.lap())});
|
|
|
|
var buf: [16]u8 = undefined;
|
|
std.log.info("player created & entering i/o loop...", .{});
|
|
while (true) {
|
|
std.debug.print("( paused = {}, volume = {d} )\n> ", .{ player.paused(), try player.volume() });
|
|
const line = (try std.io.getStdIn().reader().readUntilDelimiterOrEof(&buf, '\n')) orelse break;
|
|
var iter = std.mem.split(u8, line, ":");
|
|
const cmd = std.mem.trimRight(u8, iter.first(), &std.ascii.whitespace);
|
|
if (std.mem.eql(u8, cmd, "vol")) {
|
|
var vol = try std.fmt.parseFloat(f32, std.mem.trim(u8, iter.next().?, &std.ascii.whitespace));
|
|
try player.setVolume(vol);
|
|
} else if (std.mem.eql(u8, cmd, "pause")) {
|
|
try player.pause();
|
|
try std.testing.expect(player.paused());
|
|
} else if (std.mem.eql(u8, cmd, "play")) {
|
|
try player.play();
|
|
try std.testing.expect(!player.paused());
|
|
} else if (std.mem.eql(u8, cmd, "exit")) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
const pitch = 440.0;
|
|
const radians_per_second = pitch * 2.0 * std.math.pi;
|
|
var seconds_offset: f32 = 0.0;
|
|
fn writeCallback(_: ?*anyopaque, frames: usize) void {
|
|
const seconds_per_frame = 1.0 / @intToFloat(f32, player.sampleRate());
|
|
for (0..frames) |fi| {
|
|
const sample = std.math.sin((seconds_offset + @intToFloat(f32, fi) * seconds_per_frame) * radians_per_second);
|
|
player.writeAll(fi, sample);
|
|
}
|
|
seconds_offset = @mod(seconds_offset + seconds_per_frame * @intToFloat(f32, frames), 1.0);
|
|
}
|
|
|
|
fn deviceChange(_: ?*anyopaque) void {
|
|
std.debug.print("Device change detected!\n", .{});
|
|
}
|