|
|
|
|
@ -40,9 +40,6 @@ struct voice_recorder {
|
|
|
|
|
int preset; |
|
|
|
|
|
|
|
|
|
float peak_level; |
|
|
|
|
float waveform_levels[100]; |
|
|
|
|
int waveform_count; |
|
|
|
|
int64_t next_wf_time_ms; |
|
|
|
|
|
|
|
|
|
int64_t start_time_ms; |
|
|
|
|
}; |
|
|
|
|
@ -110,6 +107,10 @@ void voice_recorder_deinit(void) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int voice_recorder_start(const char* channel_id, int sample_rate, int channels) { |
|
|
|
|
if (!channel_id || !channel_id[0] || strlen(channel_id) >= 64 || sample_rate != 48000 || channels != 1) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "voice start: invalid target or capture format rate=%d channels=%d", sample_rate, channels); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
pthread_mutex_lock(&g_init_mtx); |
|
|
|
|
if (!g_rec) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "voice_recorder_start: not initialized (g_rec=NULL)"); |
|
|
|
|
@ -124,8 +125,6 @@ int voice_recorder_start(const char* channel_id, int sample_rate, int channels)
|
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (sample_rate <= 0) sample_rate = 48000; |
|
|
|
|
if (channels <= 0) channels = 1; |
|
|
|
|
g_rec->sample_rate = sample_rate; |
|
|
|
|
g_rec->channels = channels; |
|
|
|
|
g_rec->frame_samples = sample_rate * FRAME_MS / 1000; |
|
|
|
|
@ -133,8 +132,6 @@ int voice_recorder_start(const char* channel_id, int sample_rate, int channels)
|
|
|
|
|
|
|
|
|
|
g_rec->pcm_count = 0; |
|
|
|
|
g_rec->active = 1; |
|
|
|
|
g_rec->waveform_count = 0; |
|
|
|
|
g_rec->next_wf_time_ms = 0; |
|
|
|
|
|
|
|
|
|
struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); |
|
|
|
|
g_rec->start_time_ms = ts.tv_sec * 1000LL + ts.tv_nsec / 1000000LL; |
|
|
|
|
@ -165,14 +162,6 @@ int voice_recorder_feed(const int16_t* samples, int count) {
|
|
|
|
|
sum_sq += v * v; float av = fabsf(v); if (av > peak) peak = av; |
|
|
|
|
} |
|
|
|
|
g_rec->peak_level = (sqrtf(sum_sq / (float)count) * 2.0f + peak) / 2.0f; |
|
|
|
|
|
|
|
|
|
/* accumulate waveform level every ~100ms */ |
|
|
|
|
{ int64_t now = now_ms(); |
|
|
|
|
if (g_rec->waveform_count < 100 && now >= g_rec->next_wf_time_ms) { |
|
|
|
|
g_rec->waveform_levels[g_rec->waveform_count++] = g_rec->peak_level; |
|
|
|
|
g_rec->next_wf_time_ms = now + 100; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (g_rec->compressor && g_rec->compressor_enabled) { |
|
|
|
|
@ -228,6 +217,7 @@ int voice_recorder_stop(int* out_duration_ms) {
|
|
|
|
|
if (g_rec->compressor && g_rec->compressor_enabled) { |
|
|
|
|
struct audio_compressor* replacement = audio_compressor_clone_config(g_rec->compressor); |
|
|
|
|
if (!replacement) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "voice stop: replacement compressor allocation failed"); |
|
|
|
|
u_free(req); u_free(post); voice_cleanup_locked(g_rec); |
|
|
|
|
pthread_mutex_unlock(&g_rec->mtx); pthread_mutex_unlock(&g_init_mtx); return -1; |
|
|
|
|
} |
|
|
|
|
|