| // Copyright 2020 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ml/soda.h" |
| |
| #include <base/files/file_path.h> |
| #include <base/logging.h> |
| #include <base/native_library.h> |
| |
| namespace ml { |
| |
| namespace { |
| |
| constexpr char kSodaLibraryPath[] = |
| "/opt/google/chrome/ml_models/soda/libsoda.so"; |
| |
| } // namespace |
| |
| SodaLibrary::SodaLibrary() |
| : status_(Status::kUninitialized), |
| create_soda_async_(nullptr), |
| add_audio_(nullptr), |
| delete_soda_async_(nullptr) { |
| // Load the library with an option preferring own symbols. Otherwise the |
| // library will try to call, e.g., external tflite, which leads to crash. |
| base::NativeLibraryOptions native_library_options; |
| native_library_options.prefer_own_symbols = true; |
| library_.emplace(base::LoadNativeLibraryWithOptions( |
| base::FilePath(kSodaLibraryPath), native_library_options, nullptr)); |
| if (!library_->is_valid()) { |
| status_ = Status::kLoadLibraryFailed; |
| return; |
| } |
| |
| // Helper macro to look up functions from the library, assuming the function |
| // pointer type is named as (name+"Fn"), which is the case in |
| // "libhandwriting/interface.h". |
| #define ML_SODA_LOOKUP_FUNCTION(function_ptr, name) \ |
| function_ptr = \ |
| reinterpret_cast<name##Fn>(library_->GetFunctionPointer(#name)); \ |
| if (function_ptr == NULL) { \ |
| status_ = Status::kFunctionLookupFailed; \ |
| return; \ |
| } |
| // Look up the function pointers. |
| ML_SODA_LOOKUP_FUNCTION(create_soda_async_, CreateSodaAsync); |
| ML_SODA_LOOKUP_FUNCTION(add_audio_, AddAudio); |
| ML_SODA_LOOKUP_FUNCTION(delete_soda_async_, DeleteSodaAsync); |
| |
| ML_SODA_LOOKUP_FUNCTION(create_extended_soda_async_, CreateExtendedSodaAsync); |
| ML_SODA_LOOKUP_FUNCTION(delete_extended_soda_async_, DeleteExtendedSodaAsync); |
| ML_SODA_LOOKUP_FUNCTION(extended_add_audio_, ExtendedAddAudio); |
| ML_SODA_LOOKUP_FUNCTION(extended_soda_stop_, ExtendedSodaStop); |
| ML_SODA_LOOKUP_FUNCTION(extended_soda_start_, ExtendedSodaStart); |
| ML_SODA_LOOKUP_FUNCTION(extended_soda_mark_done_, ExtendedSodaMarkDone); |
| #undef ML_SODA_LOOKUP_FUNCTION |
| |
| status_ = Status::kOk; |
| } |
| |
| SodaLibrary::Status SodaLibrary::GetStatus() const { |
| return status_; |
| } |
| |
| SodaLibrary* SodaLibrary::GetInstance() { |
| static base::NoDestructor<SodaLibrary> instance; |
| return instance.get(); |
| } |
| |
| // Proxy functions to the library function pointers. |
| void* SodaLibrary::CreateSodaAsync(const SodaConfig& config) const { |
| DCHECK(status_ == Status::kOk); |
| return (*create_soda_async_)(config); |
| } |
| |
| void SodaLibrary::AddAudio(void* soda_async_handle, |
| const char* audio_buffer, |
| int audio_buffer_size) const { |
| DCHECK(status_ == Status::kOk); |
| (*add_audio_)(soda_async_handle, audio_buffer, audio_buffer_size); |
| } |
| |
| void SodaLibrary::AddAudio(void* soda_async_handle, |
| const std::string& audio_buffer) const { |
| AddAudio(soda_async_handle, audio_buffer.c_str(), audio_buffer.size()); |
| } |
| |
| void SodaLibrary::DeleteSodaAsync(void* soda_async_handle) const { |
| DCHECK(status_ == Status::kOk); |
| (*delete_soda_async_)(soda_async_handle); |
| } |
| |
| // Extended APIs |
| void* SodaLibrary::CreateExtendedSodaAsync( |
| const ExtendedSodaConfig& config) const { |
| DCHECK(status_ == Status::kOk); |
| return (*create_extended_soda_async_)(config); |
| } |
| |
| void SodaLibrary::DeleteExtendedSodaAsync( |
| void* extended_soda_async_handle) const { |
| DCHECK(status_ == Status::kOk); |
| (*delete_extended_soda_async_)(extended_soda_async_handle); |
| } |
| |
| void SodaLibrary::ExtendedAddAudio(void* extended_soda_async_handle, |
| const std::string& audio) const { |
| DCHECK(status_ == Status::kOk); |
| (*extended_add_audio_)(extended_soda_async_handle, audio.c_str(), |
| audio.size()); |
| } |
| |
| void SodaLibrary::ExtendedSodaStop(void* extended_soda_async_handle) const { |
| DCHECK(status_ == Status::kOk); |
| (*extended_soda_stop_)(extended_soda_async_handle); |
| } |
| |
| void SodaLibrary::ExtendedSodaStart(void* extended_soda_async_handle) const { |
| DCHECK(status_ == Status::kOk); |
| (*extended_soda_start_)(extended_soda_async_handle); |
| } |
| |
| void SodaLibrary::ExtendedSodaMarkDone(void* extended_soda_async_handle) const { |
| DCHECK(status_ == Status::kOk); |
| (*extended_soda_mark_done_)(extended_soda_async_handle); |
| } |
| |
| } // namespace ml |