Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4dbd14f423 | ||
|
|
652d775c8c |
+41
-2
@@ -11,6 +11,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
typedef struct {
|
||||
GtkApplication *app;
|
||||
@@ -42,6 +43,8 @@ typedef struct {
|
||||
unsigned int meter_timer_id;
|
||||
float live_peak;
|
||||
int runtime_ready;
|
||||
char last_transcript[4096];
|
||||
double last_transcript_time;
|
||||
} gui_state_t;
|
||||
|
||||
static float clampf(float v, float lo, float hi) {
|
||||
@@ -163,6 +166,28 @@ static int peak_is_speech(const float *samples, size_t count, float threshold) {
|
||||
return peak_abs >= threshold;
|
||||
}
|
||||
|
||||
static double monotonic_seconds(void) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (double)ts.tv_sec + (double)ts.tv_nsec / 1000000000.0;
|
||||
}
|
||||
|
||||
static int is_duplicate_transcript(gui_state_t *s, const char *text) {
|
||||
if (!s || !text || text[0] == '\0') return 0;
|
||||
if (s->last_transcript[0] == '\0') return 0;
|
||||
|
||||
const double dt = monotonic_seconds() - s->last_transcript_time;
|
||||
if (dt < 0.0 || dt > 1.0) return 0;
|
||||
|
||||
return strcmp(s->last_transcript, text) == 0;
|
||||
}
|
||||
|
||||
static void remember_transcript(gui_state_t *s, const char *text) {
|
||||
if (!s || !text || text[0] == '\0') return;
|
||||
snprintf(s->last_transcript, sizeof(s->last_transcript), "%s", text);
|
||||
s->last_transcript_time = monotonic_seconds();
|
||||
}
|
||||
|
||||
static void process_segment(gui_state_t *s, float *samples, size_t count) {
|
||||
if (!samples || count == 0) {
|
||||
free(samples);
|
||||
@@ -178,7 +203,13 @@ static void process_segment(gui_state_t *s, float *samples, size_t count) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(s->type_check))) {
|
||||
int should_autotype = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(s->type_check)) ? 1 : 0;
|
||||
if (should_autotype && gtk_window_is_active(GTK_WINDOW(s->window))) {
|
||||
should_autotype = 0;
|
||||
fprintf(stderr, "gui: autotype skipped because voice_linux window is focused\n");
|
||||
}
|
||||
|
||||
if (should_autotype) {
|
||||
if (typer_capture_focus() != 0) {
|
||||
fprintf(stderr, "gui: failed to capture focus target for autotype\n");
|
||||
}
|
||||
@@ -200,9 +231,16 @@ static void process_segment(gui_state_t *s, float *samples, size_t count) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_duplicate_transcript(s, text)) {
|
||||
fprintf(stderr, "gui: suppressed duplicate transcript within 1s window\n");
|
||||
set_status(s, "Duplicate segment suppressed");
|
||||
free(text);
|
||||
return;
|
||||
}
|
||||
|
||||
append_transcript(s, text);
|
||||
|
||||
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(s->type_check))) {
|
||||
if (should_autotype) {
|
||||
if (typer_type_text(text) != 0) {
|
||||
fprintf(stderr, "gui: autotype injection failed\n");
|
||||
set_status(s, "Autotype failed (see terminal logs)");
|
||||
@@ -211,6 +249,7 @@ static void process_segment(gui_state_t *s, float *samples, size_t count) {
|
||||
}
|
||||
}
|
||||
|
||||
remember_transcript(s, text);
|
||||
set_status(s, audio_msg);
|
||||
free(text);
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
#ifndef VOICE_VERSION_H
|
||||
#define VOICE_VERSION_H
|
||||
|
||||
#define VOICE_LINUX_VERSION "v0.0.5"
|
||||
#define VOICE_LINUX_VERSION "v0.0.6"
|
||||
#define VOICE_LINUX_VERSION_MAJOR 0
|
||||
#define VOICE_LINUX_VERSION_MINOR 0
|
||||
#define VOICE_LINUX_VERSION_PATCH 5
|
||||
#define VOICE_LINUX_VERSION_PATCH 6
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user