remove demo - we will use. Also add --exec handling
This commit is contained in:
parent
6fe5bba155
commit
3a8138c901
2 changed files with 42 additions and 34 deletions
|
@ -46,9 +46,9 @@ pub fn build(b: *std.Build) void {
|
|||
|
||||
b.installArtifact(stt_lib);
|
||||
|
||||
// Create the demo executable
|
||||
// Create the executable
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "stt-demo",
|
||||
.name = "stt",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = target,
|
||||
|
@ -114,7 +114,7 @@ pub fn build(b: *std.Build) void {
|
|||
|
||||
const run_dedicated_unit_tests = b.addRunArtifact(dedicated_unit_tests);
|
||||
|
||||
// Creates a step for unit testing the demo application
|
||||
// Creates a step for unit testing the application
|
||||
const exe_unit_tests = b.addTest(.{
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
|
|
70
src/main.zig
70
src/main.zig
|
@ -1,7 +1,4 @@
|
|||
//! STT Library Demo Application
|
||||
//!
|
||||
//! This demonstrates how to use the STT library for speech recognition
|
||||
//! with callback-based event handling and proper resource management.
|
||||
//! STT with callback-based event handling
|
||||
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
@ -11,29 +8,38 @@ const stt = @import("stt.zig");
|
|||
var should_exit = std.atomic.Value(bool).init(false);
|
||||
|
||||
/// Demo implementation of speech event handler with comprehensive error handling
|
||||
const DemoHandler = struct {
|
||||
const SpeechHandler = struct {
|
||||
speech_count: u32 = 0,
|
||||
error_count: u32 = 0,
|
||||
warning_count: u32 = 0,
|
||||
recoverable_error_count: u32 = 0,
|
||||
exec_program: ?[]const u8 = null,
|
||||
|
||||
/// Handle detected speech
|
||||
fn onSpeech(ctx: *anyopaque, text: []const u8) void {
|
||||
if (builtin.is_test) return; // Suppress output during tests
|
||||
|
||||
const self: *DemoHandler = @ptrCast(@alignCast(ctx));
|
||||
const self: *SpeechHandler = @ptrCast(@alignCast(ctx));
|
||||
self.speech_count += 1;
|
||||
|
||||
// Print with timestamp for better demo experience
|
||||
// Print with timestamp for better experience
|
||||
const timestamp = std.time.timestamp();
|
||||
std.debug.print("[{}] Speech #{}: {s}\n", .{ timestamp, self.speech_count, text });
|
||||
|
||||
// Execute program if specified
|
||||
if (self.exec_program) |program| {
|
||||
var child = std.process.Child.init(&[_][]const u8{ program, text }, std.heap.page_allocator);
|
||||
_ = child.spawn() catch |err| {
|
||||
std.log.err("Failed to execute program '{s}': {}", .{ program, err });
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle basic errors (fallback for compatibility)
|
||||
fn onError(ctx: *anyopaque, error_code: stt.SttError, message: []const u8) void {
|
||||
if (builtin.is_test) return; // Suppress output during tests
|
||||
|
||||
const self: *DemoHandler = @ptrCast(@alignCast(ctx));
|
||||
const self: *SpeechHandler = @ptrCast(@alignCast(ctx));
|
||||
self.error_count += 1;
|
||||
|
||||
// Print error with timestamp
|
||||
|
@ -43,13 +49,13 @@ const DemoHandler = struct {
|
|||
|
||||
/// Handle detailed errors with comprehensive information
|
||||
fn onDetailedError(ctx: *anyopaque, error_info: stt.SttErrorInfo) void {
|
||||
const self: *DemoHandler = @ptrCast(@alignCast(ctx));
|
||||
const self: *SpeechHandler = @ptrCast(@alignCast(ctx));
|
||||
|
||||
logDetail(self, error_info) catch |e|
|
||||
std.log.err("Error writing error {}. Original message: {s}", .{ e, error_info.message });
|
||||
}
|
||||
|
||||
fn logDetail(self: *DemoHandler, error_info: stt.SttErrorInfo) !void {
|
||||
fn logDetail(self: *SpeechHandler, error_info: stt.SttErrorInfo) !void {
|
||||
const log = std.log.scoped(.stt);
|
||||
// Categorize the error for statistics
|
||||
if (error_info.recoverable)
|
||||
|
@ -106,7 +112,7 @@ const DemoHandler = struct {
|
|||
}
|
||||
|
||||
/// Get comprehensive statistics for summary
|
||||
fn getStats(self: *const DemoHandler) struct {
|
||||
fn getStats(self: *const SpeechHandler) struct {
|
||||
speech_count: u32,
|
||||
error_count: u32,
|
||||
warning_count: u32,
|
||||
|
@ -156,29 +162,31 @@ pub fn main() !void {
|
|||
});
|
||||
_ = c.signal(c.SIGINT, signalHandler);
|
||||
|
||||
// Create demo handler with statistics tracking
|
||||
var demo_handler = DemoHandler{};
|
||||
const speech_handler = stt.SpeechEventHandler{
|
||||
.onSpeechFn = DemoHandler.onSpeech,
|
||||
.onErrorFn = DemoHandler.onError,
|
||||
.onDetailedErrorFn = DemoHandler.onDetailedError,
|
||||
.ctx = &demo_handler,
|
||||
};
|
||||
|
||||
// Parse command line arguments
|
||||
const args = try std.process.argsAlloc(allocator);
|
||||
defer std.process.argsFree(allocator, args);
|
||||
|
||||
var model_path: ?[]const u8 = null;
|
||||
var exec_program: ?[]const u8 = null;
|
||||
|
||||
// Parse --model argument
|
||||
// Parse --model and --exec arguments
|
||||
for (args[1..]) |arg| {
|
||||
if (std.mem.startsWith(u8, arg, "--model=")) {
|
||||
model_path = arg[8..]; // Skip "--model="
|
||||
break;
|
||||
} else if (std.mem.startsWith(u8, arg, "--exec=")) {
|
||||
exec_program = arg[7..]; // Skip "--exec="
|
||||
}
|
||||
}
|
||||
|
||||
// Create handler with statistics tracking
|
||||
var handler = SpeechHandler{ .exec_program = exec_program };
|
||||
const speech_handler = stt.SpeechEventHandler{
|
||||
.onSpeechFn = SpeechHandler.onSpeech,
|
||||
.onErrorFn = SpeechHandler.onError,
|
||||
.onDetailedErrorFn = SpeechHandler.onDetailedError,
|
||||
.ctx = &handler,
|
||||
};
|
||||
|
||||
// If no model specified, try default locations
|
||||
const default_paths = [_][]const u8{
|
||||
"vosk-model-small-en-us-0.15",
|
||||
|
@ -197,7 +205,7 @@ pub fn main() !void {
|
|||
// Check if model path exists
|
||||
if (model_path == null) {
|
||||
_ = try stderr.writeAll("Error: Vosk model not found.\n\n");
|
||||
_ = try stderr.writeAll("Usage: stt-demo [--model=<path>]\n\n");
|
||||
_ = try stderr.writeAll("Usage: stt [--model=<path>] [--exec=<program>]\n\n");
|
||||
_ = try stderr.writeAll("Locations searched:\n");
|
||||
inline for (default_paths) |path|
|
||||
_ = try stderr.writeAll("\t" ++ path ++ "\n");
|
||||
|
@ -289,8 +297,8 @@ pub fn main() !void {
|
|||
_ = stdout.writeAll("\n----------------------------------------\n") catch {};
|
||||
_ = stdout.writeAll("Shutdown signal received, stopping...\n") catch {};
|
||||
|
||||
// Get final statistics from demo handler
|
||||
const stats = demo_handler.getStats();
|
||||
// Get final statistics from handler
|
||||
const stats = handler.getStats();
|
||||
std.log.info("Demo Session Summary:", .{});
|
||||
std.log.info(" Speech detections: {}", .{stats.speech_count});
|
||||
std.log.info(" Fatal errors: {}", .{stats.error_count});
|
||||
|
@ -304,15 +312,15 @@ pub fn main() !void {
|
|||
_ = stdout.writeAll("Session completed successfully.\n") catch {};
|
||||
}
|
||||
|
||||
// Test the demo functionality
|
||||
test "demo handler functionality" {
|
||||
// Test the functionality
|
||||
test "handler functionality" {
|
||||
const testing = std.testing;
|
||||
|
||||
var demo_handler = DemoHandler{};
|
||||
var handler = SpeechHandler{};
|
||||
const speech_handler = stt.SpeechEventHandler{
|
||||
.onSpeechFn = DemoHandler.onSpeech,
|
||||
.onErrorFn = DemoHandler.onError,
|
||||
.ctx = &demo_handler,
|
||||
.onSpeechFn = SpeechHandler.onSpeech,
|
||||
.onErrorFn = SpeechHandler.onError,
|
||||
.ctx = &handler,
|
||||
};
|
||||
|
||||
// Test that callbacks can be invoked without crashing
|
||||
|
|
Loading…
Add table
Reference in a new issue