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