Update to 1.4.11
This commit is contained in:
@@ -24,6 +24,9 @@ NAN_MODULE_INIT(AudioConsumerWrapper::Init) {
|
||||
Nan::SetPrototypeMethod(klass, "create_filter_threshold", AudioConsumerWrapper::_create_filter_threshold);
|
||||
Nan::SetPrototypeMethod(klass, "create_filter_state", AudioConsumerWrapper::_create_filter_state);
|
||||
|
||||
Nan::SetPrototypeMethod(klass, "get_filter_mode", AudioConsumerWrapper::_get_filter_mode);
|
||||
Nan::SetPrototypeMethod(klass, "set_filter_mode", AudioConsumerWrapper::_set_filter_mode);
|
||||
|
||||
constructor_template().Reset(klass);
|
||||
constructor().Reset(Nan::GetFunction(klass).ToLocalChecked());
|
||||
}
|
||||
@@ -92,7 +95,7 @@ void AudioConsumerWrapper::do_wrap(const v8::Local<v8::Object> &obj) {
|
||||
|
||||
v8::Local<v8::Value> argv[1];
|
||||
argv[0] = js_fbuffer;
|
||||
callback_function.As<v8::Function>()->Call(Nan::GetCurrentContext(), Nan::Undefined(), 1, argv);
|
||||
(void) callback_function.As<v8::Function>()->Call(Nan::GetCurrentContext(), Nan::Undefined(), 1, argv);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -103,7 +106,7 @@ void AudioConsumerWrapper::do_wrap(const v8::Local<v8::Object> &obj) {
|
||||
v8::Local<v8::Value> callback_function = Nan::Get(handle, Nan::New<v8::String>("callback_ended").ToLocalChecked()).FromMaybe(v8::Local<v8::Value>{});
|
||||
if(callback_function.IsEmpty() || callback_function->IsNullOrUndefined() || !callback_function->IsFunction())
|
||||
return;
|
||||
callback_function.As<v8::Function>()->Call(Nan::GetCurrentContext(), Nan::Undefined(), 0, nullptr);
|
||||
(void) callback_function.As<v8::Function>()->Call(Nan::GetCurrentContext(), Nan::Undefined(), 0, nullptr);
|
||||
});
|
||||
|
||||
this->_call_started = Nan::async_callback([&]{
|
||||
@@ -113,7 +116,7 @@ void AudioConsumerWrapper::do_wrap(const v8::Local<v8::Object> &obj) {
|
||||
v8::Local<v8::Value> callback_function = Nan::Get(handle, Nan::New<v8::String>("callback_started").ToLocalChecked()).FromMaybe(v8::Local<v8::Value>{});
|
||||
if(callback_function.IsEmpty() || callback_function->IsNullOrUndefined() || !callback_function->IsFunction())
|
||||
return;
|
||||
callback_function.As<v8::Function>()->Call(Nan::GetCurrentContext(), Nan::Undefined(), 0, nullptr);
|
||||
(void) callback_function.As<v8::Function>()->Call(Nan::GetCurrentContext(), Nan::Undefined(), 0, nullptr);
|
||||
});
|
||||
|
||||
Nan::Set(this->handle(), Nan::New<v8::String>("frame_size").ToLocalChecked(), Nan::New<v8::Number>((uint32_t) this->_handle->frame_size));
|
||||
@@ -131,32 +134,43 @@ void AudioConsumerWrapper::unbind() {
|
||||
void AudioConsumerWrapper::process_data(const void *buffer, size_t samples) {
|
||||
lock_guard lock(this->execute_lock);
|
||||
|
||||
auto filters = this->filters();
|
||||
for(const auto& filter : filters) {
|
||||
auto _filter = filter->filter();
|
||||
if(!_filter) continue;
|
||||
bool should_process{true};
|
||||
if(this->filter_mode_ == FilterMode::FILTER) {
|
||||
auto filters = this->filters();
|
||||
for(const auto& filter : filters) {
|
||||
auto _filter = filter->filter();
|
||||
if(!_filter) continue;
|
||||
|
||||
if(_filter->frame_size() != samples) {
|
||||
cerr << "Tried to use a filter, but frame size does not match!" << endl;
|
||||
continue;
|
||||
}
|
||||
if(!_filter->process(buffer)) {
|
||||
if(!this->last_consumed) {
|
||||
this->last_consumed = true;
|
||||
this->_call_ended();
|
||||
unique_lock native_read_lock(this->native_read_callback_lock);
|
||||
if(this->native_read_callback) {
|
||||
auto callback = this->native_read_callback; /* copy */
|
||||
native_read_lock.unlock();
|
||||
callback(nullptr, 0); /* notify end */
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(_filter->frame_size() != samples) {
|
||||
cerr << "Tried to use a filter, but frame size does not match!" << endl;
|
||||
continue;
|
||||
}
|
||||
if(!_filter->process(buffer)) {
|
||||
should_process = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if(this->filter_mode_ != FilterMode::BYPASS) {
|
||||
should_process = false;
|
||||
}
|
||||
|
||||
if(this->last_consumed)
|
||||
this->_call_started();
|
||||
if(!should_process) {
|
||||
if(!this->last_consumed) {
|
||||
this->last_consumed = true;
|
||||
this->_call_ended();
|
||||
unique_lock native_read_lock(this->native_read_callback_lock);
|
||||
if(this->native_read_callback) {
|
||||
auto callback = this->native_read_callback; /* copy */
|
||||
native_read_lock.unlock();
|
||||
callback(nullptr, 0); /* notify end */
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(this->last_consumed) {
|
||||
this->_call_started();
|
||||
}
|
||||
this->last_consumed = false;
|
||||
|
||||
{
|
||||
@@ -177,7 +191,7 @@ void AudioConsumerWrapper::process_data(const void *buffer, size_t samples) {
|
||||
buf->sample_count = samples;
|
||||
|
||||
{
|
||||
lock_guard lock(this->_data_lock);
|
||||
lock_guard data_lock{this->_data_lock};
|
||||
this->_data_entries.push_back(move(buf));
|
||||
}
|
||||
this->_call_data();
|
||||
@@ -199,8 +213,8 @@ std::shared_ptr<AudioFilterWrapper> AudioConsumerWrapper::create_filter(const st
|
||||
}
|
||||
|
||||
{
|
||||
lock_guard lock(this->_filters_lock);
|
||||
this->_filters.push_back(result);
|
||||
lock_guard lock(this->filter_mutex_);
|
||||
this->filter_.push_back(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -209,20 +223,22 @@ std::shared_ptr<AudioFilterWrapper> AudioConsumerWrapper::create_filter(const st
|
||||
void AudioConsumerWrapper::delete_filter(const AudioFilterWrapper* filter) {
|
||||
shared_ptr<AudioFilterWrapper> handle; /* need to keep the handle 'till everything has been finished */
|
||||
{
|
||||
lock_guard lock(this->_filters_lock);
|
||||
for(auto& c : this->_filters) {
|
||||
lock_guard lock(this->filter_mutex_);
|
||||
for(auto& c : this->filter_) {
|
||||
if(&*c == filter) {
|
||||
handle = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!handle)
|
||||
return;
|
||||
if(!handle) {
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
auto it = find(this->_filters.begin(), this->_filters.end(), handle);
|
||||
if(it != this->_filters.end())
|
||||
this->_filters.erase(it);
|
||||
auto it = find(this->filter_.begin(), this->filter_.end(), handle);
|
||||
if(it != this->filter_.end()) {
|
||||
this->filter_.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,4 +335,21 @@ NAN_METHOD(AudioConsumerWrapper::_create_filter_state) {
|
||||
|
||||
auto object = handle->create_filter("state", filter);
|
||||
info.GetReturnValue().Set(object->handle());
|
||||
}
|
||||
|
||||
NAN_METHOD(AudioConsumerWrapper::_get_filter_mode) {
|
||||
auto handle = ObjectWrap::Unwrap<AudioConsumerWrapper>(info.Holder());
|
||||
info.GetReturnValue().Set((int) handle->filter_mode_);
|
||||
}
|
||||
|
||||
NAN_METHOD(AudioConsumerWrapper::_set_filter_mode) {
|
||||
auto handle = ObjectWrap::Unwrap<AudioConsumerWrapper>(info.Holder());
|
||||
|
||||
if(info.Length() != 1 || !info[0]->IsNumber()) {
|
||||
Nan::ThrowError("invalid argument");
|
||||
return;
|
||||
}
|
||||
|
||||
auto value = info[0].As<v8::Number>()->ToInteger()->Value();
|
||||
handle->filter_mode_ = (FilterMode) value;
|
||||
}
|
||||
@@ -17,15 +17,12 @@ namespace tc {
|
||||
namespace recorder {
|
||||
class AudioFilterWrapper;
|
||||
class AudioRecorderWrapper;
|
||||
/*
|
||||
get_filters() : ConsumeFilter[];
|
||||
|
||||
register_filter(filter: ConsumeFilter);
|
||||
unregister_filter(filter: ConsumeFilter);
|
||||
|
||||
create_filter_vad() : VADConsumeFilter;
|
||||
create_filter_threshold() : ThresholdConsumeFilter;
|
||||
*/
|
||||
enum FilterMode {
|
||||
BYPASS,
|
||||
FILTER,
|
||||
BLOCK
|
||||
};
|
||||
|
||||
class AudioConsumerWrapper : public Nan::ObjectWrap {
|
||||
friend class AudioRecorderWrapper;
|
||||
@@ -52,14 +49,19 @@ namespace tc {
|
||||
static NAN_METHOD(_create_filter_threshold);
|
||||
static NAN_METHOD(_create_filter_state);
|
||||
|
||||
static NAN_METHOD(_get_filter_mode);
|
||||
static NAN_METHOD(_set_filter_mode);
|
||||
|
||||
std::shared_ptr<AudioFilterWrapper> create_filter(const std::string& /* name */, const std::shared_ptr<filter::Filter>& /* filter impl */);
|
||||
void delete_filter(const AudioFilterWrapper*);
|
||||
|
||||
inline std::deque<std::shared_ptr<AudioFilterWrapper>> filters() {
|
||||
std::lock_guard lock(this->_filters_lock);
|
||||
return this->_filters;
|
||||
std::lock_guard lock(this->filter_mutex_);
|
||||
return this->filter_;
|
||||
}
|
||||
|
||||
inline FilterMode filter_mode() const { return this->filter_mode_; }
|
||||
|
||||
inline std::shared_ptr<AudioConsumer> native_consumer() { return this->_handle; }
|
||||
|
||||
std::mutex native_read_callback_lock;
|
||||
@@ -70,8 +72,9 @@ namespace tc {
|
||||
std::mutex execute_lock;
|
||||
std::shared_ptr<AudioConsumer> _handle;
|
||||
|
||||
std::mutex _filters_lock;
|
||||
std::deque<std::shared_ptr<AudioFilterWrapper>> _filters;
|
||||
std::mutex filter_mutex_;
|
||||
std::deque<std::shared_ptr<AudioFilterWrapper>> filter_;
|
||||
FilterMode filter_mode_{FilterMode::FILTER};
|
||||
bool last_consumed = false;
|
||||
|
||||
void do_wrap(const v8::Local<v8::Object>& /* object */);
|
||||
@@ -95,10 +98,6 @@ namespace tc {
|
||||
Nan::callback_t<> _call_data;
|
||||
Nan::callback_t<> _call_ended;
|
||||
Nan::callback_t<> _call_started;
|
||||
/*
|
||||
callback_data: (buffer: Float32Array) => any;
|
||||
callback_ended: () => any;
|
||||
*/
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,8 +66,9 @@ AudioFilterWrapper::~AudioFilterWrapper() {
|
||||
log_free("AudioFilterWrapper", this);
|
||||
|
||||
auto threshold_filter = dynamic_pointer_cast<filter::ThresholdFilter>(this->_filter);
|
||||
if(threshold_filter)
|
||||
threshold_filter->on_analyze = nullptr;
|
||||
if(threshold_filter) {
|
||||
threshold_filter->on_analyze = nullptr;
|
||||
}
|
||||
|
||||
this->_callback_analyzed.Reset();
|
||||
}
|
||||
@@ -284,7 +285,6 @@ NAN_METHOD(AudioFilterWrapper::_set_analyze_filter) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NAN_METHOD(AudioFilterWrapper::_is_consuming) {
|
||||
auto handle = ObjectWrap::Unwrap<AudioFilterWrapper>(info.Holder());
|
||||
if(!handle->_filter) {
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace tc {
|
||||
}
|
||||
|
||||
AudioFilterWrapper(const std::string& name, const std::shared_ptr<filter::Filter>& /* handle */);
|
||||
virtual ~AudioFilterWrapper();
|
||||
~AudioFilterWrapper() override;
|
||||
|
||||
static NAN_METHOD(_get_name);
|
||||
|
||||
|
||||
@@ -181,6 +181,16 @@ NAN_MODULE_INIT(init) {
|
||||
audio::recorder::AudioRecorderWrapper::Init(namespace_record);
|
||||
audio::recorder::AudioConsumerWrapper::Init(namespace_record);
|
||||
audio::recorder::AudioFilterWrapper::Init(namespace_record);
|
||||
|
||||
{
|
||||
auto enum_object = Nan::New<v8::Object>();
|
||||
ENUM_SET(enum_object, "Bypass", audio::recorder::FilterMode::BYPASS);
|
||||
ENUM_SET(enum_object, "Filter", audio::recorder::FilterMode::FILTER);
|
||||
ENUM_SET(enum_object, "Block", audio::recorder::BLOCK);
|
||||
|
||||
Nan::DefineOwnProperty(namespace_record, Nan::New<v8::String>("FilterMode").ToLocalChecked(), enum_object, v8::DontDelete);
|
||||
}
|
||||
|
||||
Nan::Set(namespace_audio, Nan::New<v8::String>("record").ToLocalChecked(), namespace_record);
|
||||
}
|
||||
{
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace tc::connection {
|
||||
void process_packet(uint16_t packet_id, const pipes::buffer_view& /* buffer */, codec::value /* codec */, bool /* head */);
|
||||
void execute_tick();
|
||||
|
||||
inline float get_volume() { return this->volume_; }
|
||||
inline float get_volume() const { return this->volume_; }
|
||||
inline void set_volume(float value) { this->volume_ = value; }
|
||||
|
||||
inline state::value state() { return this->state_; }
|
||||
@@ -121,7 +121,7 @@ namespace tc::connection {
|
||||
uint16_t last_packet_id{0xFFFF}; /* the first packet id is 0 so one packet before is 0xFFFF */
|
||||
std::chrono::system_clock::time_point last_packet_timestamp;
|
||||
|
||||
inline std::chrono::system_clock::time_point stream_timeout() {
|
||||
inline std::chrono::system_clock::time_point stream_timeout() const {
|
||||
return this->last_packet_timestamp + std::chrono::milliseconds{1000};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user