149 lines
4 KiB
Zig
149 lines
4 KiB
Zig
const std = @import("std");
|
|
const main = @import("main.zig");
|
|
const backends = @import("backends.zig");
|
|
const util = @import("util.zig");
|
|
|
|
pub const min_sample_rate = 8_000; // Hz
|
|
pub const max_sample_rate = 5_644_800; // Hz
|
|
|
|
const dummy_playback = main.Device{
|
|
.id = "dummy-playback",
|
|
.name = "Dummy Device",
|
|
.mode = .playback,
|
|
.channels = undefined,
|
|
.formats = std.meta.tags(main.Format),
|
|
.sample_rate = .{
|
|
.min = min_sample_rate,
|
|
.max = max_sample_rate,
|
|
},
|
|
};
|
|
|
|
const dummy_capture = main.Device{
|
|
.id = "dummy-capture",
|
|
.name = "Dummy Device",
|
|
.mode = .capture,
|
|
.channels = undefined,
|
|
.formats = std.meta.tags(main.Format),
|
|
.sample_rate = .{
|
|
.min = min_sample_rate,
|
|
.max = max_sample_rate,
|
|
},
|
|
};
|
|
|
|
pub const Context = struct {
|
|
allocator: std.mem.Allocator,
|
|
devices_info: util.DevicesInfo,
|
|
|
|
pub fn init(allocator: std.mem.Allocator, options: main.Context.Options) !backends.BackendContext {
|
|
_ = options;
|
|
|
|
var self = try allocator.create(Context);
|
|
errdefer allocator.destroy(self);
|
|
self.* = .{
|
|
.allocator = allocator,
|
|
.devices_info = util.DevicesInfo.init(),
|
|
};
|
|
|
|
return .{ .dummy = self };
|
|
}
|
|
|
|
pub fn deinit(self: *Context) void {
|
|
for (self.devices_info.list.items) |d|
|
|
freeDevice(self.allocator, d);
|
|
self.devices_info.list.deinit(self.allocator);
|
|
self.allocator.destroy(self);
|
|
}
|
|
|
|
pub fn refresh(self: *Context) !void {
|
|
for (self.devices_info.list.items) |d|
|
|
freeDevice(self.allocator, d);
|
|
self.devices_info.clear(self.allocator);
|
|
|
|
try self.devices_info.list.append(self.allocator, dummy_playback);
|
|
try self.devices_info.list.append(self.allocator, dummy_capture);
|
|
self.devices_info.list.items[0].channels = try self.allocator.alloc(main.Channel, 1);
|
|
self.devices_info.list.items[0].channels[0] = .{
|
|
.id = .front_center,
|
|
};
|
|
self.devices_info.list.items[1].channels = try self.allocator.alloc(main.Channel, 1);
|
|
self.devices_info.list.items[1].channels[0] = .{
|
|
.id = .front_center,
|
|
};
|
|
self.devices_info.setDefault(.playback, 0);
|
|
self.devices_info.setDefault(.capture, 1);
|
|
}
|
|
|
|
pub fn devices(self: Context) []const main.Device {
|
|
return self.devices_info.list.items;
|
|
}
|
|
|
|
pub fn defaultDevice(self: Context, mode: main.Device.Mode) ?main.Device {
|
|
return self.devices_info.default(mode);
|
|
}
|
|
|
|
pub fn createPlayer(self: *Context, device: main.Device, writeFn: main.WriteFn, options: main.Player.Options) !backends.BackendPlayer {
|
|
_ = writeFn;
|
|
var player = try self.allocator.create(Player);
|
|
player.* = .{
|
|
.allocator = self.allocator,
|
|
.sample_rate = options.sample_rate,
|
|
.is_paused = false,
|
|
.vol = 1.0,
|
|
.channels = device.channels,
|
|
.format = options.format,
|
|
.write_step = 0,
|
|
};
|
|
return .{ .dummy = player };
|
|
}
|
|
};
|
|
|
|
pub const Player = struct {
|
|
allocator: std.mem.Allocator,
|
|
sample_rate: u24,
|
|
is_paused: bool,
|
|
vol: f32,
|
|
|
|
channels: []main.Channel,
|
|
format: main.Format,
|
|
write_step: u8,
|
|
|
|
pub fn deinit(self: *Player) void {
|
|
self.allocator.destroy(self);
|
|
}
|
|
|
|
pub fn start(self: Player) !void {
|
|
_ = self;
|
|
}
|
|
|
|
pub fn play(self: *Player) !void {
|
|
self.is_paused = false;
|
|
}
|
|
|
|
pub fn pause(self: *Player) !void {
|
|
self.is_paused = true;
|
|
}
|
|
|
|
pub fn paused(self: Player) bool {
|
|
return self.is_paused;
|
|
}
|
|
|
|
pub fn setVolume(self: *Player, vol: f32) !void {
|
|
self.vol = vol;
|
|
}
|
|
|
|
pub fn volume(self: Player) !f32 {
|
|
return self.vol;
|
|
}
|
|
|
|
pub fn sampleRate(self: Player) u24 {
|
|
return self.sample_rate;
|
|
}
|
|
};
|
|
|
|
fn freeDevice(allocator: std.mem.Allocator, device: main.Device) void {
|
|
allocator.free(device.channels);
|
|
}
|
|
|
|
test {
|
|
std.testing.refAllDeclsRecursive(@This());
|
|
}
|