class EL_AUDIO_CLIP_SAVER
Thread consumer for audio clips taken from a (thread product) work queue. Saves the clips in the temp directory with unique file names and puts the saved file path onto a (thread product) work queue for processing by another thread. Notifies a sound level listener of any audio clips which are silent (below the noise threshold)
note
description: "[
Thread consumer for audio clips taken from a (thread product) work queue.
Saves the clips in the temp directory with unique file names and puts the saved file path
onto a (thread product) work queue for processing by another thread.
Notifies a sound level listener of any audio clips which are silent (below the noise threshold)
]"
author: "Finnian Reilly"
copyright: "Copyright (c) 2001-2022 Finnian Reilly"
contact: "finnian at eiffel hyphen loop dot com"
license: "MIT license (See: en.wikipedia.org/wiki/MIT_License)"
date: "2023-03-10 10:10:55 GMT (Friday 10th March 2023)"
revision: "6"
class
EL_AUDIO_CLIP_SAVER
inherit
EL_CONSUMER_THREAD [EL_WAVE_AUDIO_16_BIT_CLIP]
rename
consume_product as save_clip,
product as audio_clip
redefine
on_start
end
EL_AUDIO_CLIP_SAVER_CONSTANTS
undefine
default_create, is_equal, copy
end
EL_MODULE_LOG
EL_MODULE_LOG_MANAGER
EL_MODULE_FILE_SYSTEM
EL_MODULE_DIRECTORY
create
make
feature {NONE} -- Initialization
make (rms_energy: REAL)
--
do
make_default
noise_threshold := rms_energy
create audio_file_processing_queue.make (0)
log.put_new_line
across Temporary_directory.files_with_extension ("wav") as wav_path loop
if wav_path.item.base.starts_with (Clip_base_name) then
File_system.remove_file (wav_path.item)
end
end
create sample_count.make
end
feature -- Access
audio_file_processing_queue: EL_THREAD_PRODUCT_QUEUE [STRING]
samples_recorded_count: INTEGER
--
do
Result := sample_count.item
end
feature -- Element change
set_sound_level_listener (a_sound_level_listener: EL_SIGNAL_LEVEL_LISTENER)
--
require
a_sound_level_listener_not_void: a_sound_level_listener /= Void
do
sound_level_listener := a_sound_level_listener
end
reset_sample_count
--
do
sample_count.set_item (0)
end
set_signal_threshold (rms_energy: REAL)
--
do
noise_threshold := rms_energy
end
feature {NONE} -- Implementation
save_clip
--
local
clip_name: ZSTRING; audio_rms_energy: REAL
do
audio_rms_energy := audio_clip.rms_energy
if sound_level_listener /= Void then
sound_level_listener.set_signal_level (audio_rms_energy)
end
sample_count.add (audio_clip.sample_count)
if audio_rms_energy > noise_threshold then
log.enter ("save_clip")
clip_count := clip_count + 1
clip_name := unique_clip_name (clip_count)
audio_clip.save (Directory.temporary + clip_name)
log.put_string_field ("File name", clip_name)
log.put_new_line
audio_file_processing_queue.put (clip_name)
log.exit
else
audio_file_processing_queue.put (Silent_clip_name)
end
end
on_start
do
Log_manager.add_thread (Current)
end
unique_clip_name (n: INTEGER): ZSTRING
--
local
n_string: STRING
do
Result := Clip_base_name.twin
n_string := (n + Clip_no_base).out
n_string.remove_head (1)
Result.append_all_general (<< "-", n_string, ".wav" >>)
end
feature {NONE} -- Internal attributes
clip_count: INTEGER
sound_level_listener: EL_SIGNAL_LEVEL_LISTENER
sample_count: EL_MUTEX_NUMERIC [INTEGER]
noise_threshold: REAL
feature -- Constants
Temporary_directory: EL_DIRECTORY
--
once
create Result.make (Directory.temporary)
end
end