Skip to content

Commit

Permalink
Update XMOS adapter classes to comply with v1.26.0
Browse files Browse the repository at this point in the history
  • Loading branch information
xluciano committed Jun 29, 2022
1 parent 667ba47 commit e5c63e4
Show file tree
Hide file tree
Showing 13 changed files with 230 additions and 63 deletions.
5 changes: 5 additions & 0 deletions applications/acsdkXMOSAdapter/GPIO/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@ project(GPIO LANGUAGES CXX)

include(${AVS_CMAKE_BUILD}/BuildDefaults.cmake)

set(KWD_ADAPTER_REGISTRATION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/acsdkKWDProvider/src/GPIORegistration.cpp" PARENT_SCOPE)
set(KWD_COMPONENT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/acsdkKWD/src/KWDComponent.cpp" PARENT_SCOPE)

set(TARGET_KWD_LIB "GPIO" PARENT_SCOPE)

add_subdirectory("src")
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,26 @@ using namespace avsCommon::sdkInterfaces;
class GPIOKeywordDetector : public XMOSKeywordDetector {
public:
/**
* Creates a @c GPIOKeywordDetector.
*
* @param stream The stream of audio data. This should be formatted in LPCM encoded with 16 bits per sample and
* have a sample rate of 16 kHz. Additionally, the data should be in little endian format.
* @param audioFormat The format of the audio data located within the stream.
* @param keyWordNotifier The object with which to notifiy observers of keyword detections.
* @param KeyWordDetectorStateNotifier The object with which to notify observers of state changes in the engine.
* @param msToPushPerIteration The amount of data in milliseconds to push to the cloud at a time. This was the amount used by
* Sensory in example code.
* @return A new @c GPIOKeywordDetector, or @c nullptr if the operation failed.
*/
static std::unique_ptr<GPIOKeywordDetector> create(
const std::shared_ptr<AudioInputStream> stream,
const std::shared_ptr<avsCommon::utils::AudioFormat>& audioFormat,
std::shared_ptr<acsdkKWDInterfaces::KeywordNotifierInterface> keyWordNotifier,
std::shared_ptr<acsdkKWDInterfaces::KeywordDetectorStateNotifierInterface> KeyWordDetectorStateNotifier,
std::chrono::milliseconds msToPushPerIteration = std::chrono::milliseconds(10));

/**
* @deprecated
* Creates a @c GPIOKeywordDetector.
*
* @param stream The stream of audio data. This should be formatted in LPCM encoded with 16 bits per sample and
Expand Down Expand Up @@ -72,15 +92,15 @@ class GPIOKeywordDetector : public XMOSKeywordDetector {
* @param stream The stream of audio data. This should be formatted in LPCM encoded with 16 bits per sample and
* have a sample rate of 16 kHz. Additionally, the data should be in little endian format.
* @param audioFormat The format of the audio data located within the stream.
* @param keyWordObservers The observers to notify of keyword detections.
* @param keyWordDetectorStateObservers The observers to notify of state changes in the engine.
* @param keywordNotifier The object with which to notifiy observers of keyword detections.
* @param KeywordDetectorStateNotifier The object with which to notify observers of state changes in the engine.
* @param msToPushPerIteration The amount of data in milliseconds to push to the cloud at a time. This was the amount used by
* Sensory in example code.
*/
GPIOKeywordDetector(
std::shared_ptr<AudioInputStream> stream,
std::unordered_set<std::shared_ptr<KeyWordObserverInterface>> keyWordObservers,
std::unordered_set<std::shared_ptr<KeyWordDetectorStateObserverInterface>> keyWordDetectorStateObservers,
const std::shared_ptr<acsdkKWDInterfaces::KeywordNotifierInterface> keywordNotifier,
const std::shared_ptr<acsdkKWDInterfaces::KeywordDetectorStateNotifierInterface> KeywordDetectorStateNotifier,
avsCommon::utils::AudioFormat audioFormat,
std::chrono::milliseconds msToPushPerIteration = std::chrono::milliseconds(10));

Expand Down
13 changes: 9 additions & 4 deletions applications/acsdkXMOSAdapter/GPIO/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
add_definitions("-DACSDK_LOG_MODULE=GPIOKeywordDetector")
add_library(GPIO SHARED

add_library(GPIO
GPIOKeywordDetector.cpp)

target_include_directories(GPIO PUBLIC
"${KWD_SOURCE_DIR}/include"
"${XMOS_SOURCE_DIR}/include"
"${GPIO_SOURCE_DIR}/../XMOS/include"
"${GPIO_SOURCE_DIR}/include")

target_link_libraries(GPIO XMOS KWD AVSCommon wiringPi)
target_link_libraries(GPIO
XMOS
acsdkKWDImplementations
acsdkKWDInterfaces
AVSCommon
wiringPi)

# install target
asdk_install()
38 changes: 33 additions & 5 deletions applications/acsdkXMOSAdapter/GPIO/src/GPIOKeywordDetector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
#include <fcntl.h>
#include <sys/ioctl.h>

#include <acsdkKWDImplementations/KWDNotifierFactories.h>
#include <AVSCommon/Utils/Logger/Logger.h>

#include "GPIO/GPIOKeywordDetector.h"

namespace alexaClientSDK {
Expand Down Expand Up @@ -94,26 +96,52 @@ bool GPIOKeywordDetector::openDevice() {
return true;
}

// Deprecated create method.
std::unique_ptr<GPIOKeywordDetector> GPIOKeywordDetector::create(
std::shared_ptr<AudioInputStream> stream,
avsCommon::utils::AudioFormat audioFormat,
std::unordered_set<std::shared_ptr<KeyWordObserverInterface>> keyWordObservers,
std::unordered_set<std::shared_ptr<KeyWordDetectorStateObserverInterface>> keyWordDetectorStateObservers,
std::chrono::milliseconds msToPushPerIteration) {
// Create Notifiers to be used instead of the observers.
auto keywordNotifier = acsdkKWDImplementations::KWDNotifierFactories::createKeywordNotifier();
for (auto kwObserver : keyWordObservers) {
keywordNotifier->addObserver(kwObserver);
}

auto keywordDetectorStateNotifier =
acsdkKWDImplementations::KWDNotifierFactories::createKeywordDetectorStateNotifier();
for (auto kwdStateObserver : keyWordDetectorStateObservers) {
keywordDetectorStateNotifier->addObserver(kwdStateObserver);
}

return create(
stream,
std::make_shared<avsCommon::utils::AudioFormat>(audioFormat),
keywordNotifier,
keywordDetectorStateNotifier,
msToPushPerIteration);
}

std::unique_ptr<GPIOKeywordDetector> GPIOKeywordDetector::create(
std::shared_ptr<avsCommon::avs::AudioInputStream> stream,
const std::shared_ptr<avsCommon::utils::AudioFormat>& audioFormat,
const std::shared_ptr<acsdkKWDInterfaces::KeywordNotifierInterface> keywordNotifier,
const std::shared_ptr<acsdkKWDInterfaces::KeywordDetectorStateNotifierInterface> keywordDetectorStateNotifier,
std::chrono::milliseconds msToPushPerIteration) {
if (!stream) {
ACSDK_ERROR(LX("createFailed").d("reason", "nullStream"));
return nullptr;
}

// TODO: ACSDK-249 - Investigate cpu usage of converting bytes between endianness and if it's not too much, do it.
if (isByteswappingRequired(audioFormat)) {
if (isByteswappingRequired(*audioFormat)) {
ACSDK_ERROR(LX("createFailed").d("reason", "endianMismatch"));
return nullptr;
}

std::unique_ptr<GPIOKeywordDetector> detector(new GPIOKeywordDetector(
stream, keyWordObservers, keyWordDetectorStateObservers, audioFormat));
stream, keywordNotifier, keywordDetectorStateNotifier, *audioFormat));

if (!detector->init()) {
ACSDK_ERROR(LX("createFailed").d("reason", "initDetectorFailed"));
Expand All @@ -125,11 +153,11 @@ std::unique_ptr<GPIOKeywordDetector> GPIOKeywordDetector::create(

GPIOKeywordDetector::GPIOKeywordDetector(
std::shared_ptr<AudioInputStream> stream,
std::unordered_set<std::shared_ptr<KeyWordObserverInterface>> keyWordObservers,
std::unordered_set<std::shared_ptr<KeyWordDetectorStateObserverInterface>> keyWordDetectorStateObservers,
std::shared_ptr<acsdkKWDInterfaces::KeywordNotifierInterface> keywordNotifier,
std::shared_ptr<acsdkKWDInterfaces::KeywordDetectorStateNotifierInterface> keywordDetectorStateNotifier,
avsCommon::utils::AudioFormat audioFormat,
std::chrono::milliseconds msToPushPerIteration) :
XMOSKeywordDetector(stream, keyWordObservers, keyWordDetectorStateObservers, audioFormat, msToPushPerIteration) {
XMOSKeywordDetector(stream, keywordNotifier, keywordDetectorStateNotifier, audioFormat, msToPushPerIteration) {
}

GPIOKeywordDetector::~GPIOKeywordDetector() {
Expand Down
5 changes: 5 additions & 0 deletions applications/acsdkXMOSAdapter/HID/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@ project(HID LANGUAGES CXX)

include(${AVS_CMAKE_BUILD}/BuildDefaults.cmake)

set(KWD_ADAPTER_REGISTRATION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/acsdkKWDProvider/src/HIDRegistration.cpp" PARENT_SCOPE)
set(KWD_COMPONENT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/acsdkKWD/src/KWDComponent.cpp" PARENT_SCOPE)

set(TARGET_KWD_LIB "HID" PARENT_SCOPE)

add_subdirectory("src")
30 changes: 25 additions & 5 deletions applications/acsdkXMOSAdapter/HID/include/HID/HIDKeywordDetector.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,26 @@ using namespace avsCommon::sdkInterfaces;
class HIDKeywordDetector : public XMOSKeywordDetector {
public:
/**
* Creates a @c HIDKeywordDetector.
*
* @param stream The stream of audio data. This should be formatted in LPCM encoded with 16 bits per sample and
* have a sample rate of 16 kHz. Additionally, the data should be in little endian format.
* @param audioFormat The format of the audio data located within the stream.
* @param keyWordNotifier The object with which to notifiy observers of keyword detections.
* @param KeyWordDetectorStateNotifier The object with which to notify observers of state changes in the engine.
* @param msToPushPerIteration The amount of data in milliseconds to push to the cloud at a time. This was the amount used by
* Sensory in example code.
* @return A new @c HIDKeywordDetector, or @c nullptr if the operation failed.
*/
static std::unique_ptr<HIDKeywordDetector> create(
const std::shared_ptr<AudioInputStream> stream,
const std::shared_ptr<avsCommon::utils::AudioFormat>& audioFormat,
std::shared_ptr<acsdkKWDInterfaces::KeywordNotifierInterface> keyWordNotifier,
std::shared_ptr<acsdkKWDInterfaces::KeywordDetectorStateNotifierInterface> KeyWordDetectorStateNotifier,
std::chrono::milliseconds msToPushPerIteration = std::chrono::milliseconds(10));

/**
* @deprecated
* Creates a @c HIDKeywordDetector.
*
* @param stream The stream of audio data. This should be formatted in LPCM encoded with 16 bits per sample and
Expand All @@ -55,7 +75,7 @@ class HIDKeywordDetector : public XMOSKeywordDetector {
* @return A new @c HIDKeywordDetector, or @c nullptr if the operation failed.
*/
static std::unique_ptr<HIDKeywordDetector> create(
std::shared_ptr<AudioInputStream> stream,
const std::shared_ptr<AudioInputStream> stream,
avsCommon::utils::AudioFormat audioFormat,
std::unordered_set<std::shared_ptr<KeyWordObserverInterface>> keyWordObservers,
std::unordered_set<std::shared_ptr<KeyWordDetectorStateObserverInterface>> keyWordDetectorStateObservers,
Expand All @@ -73,15 +93,15 @@ class HIDKeywordDetector : public XMOSKeywordDetector {
* @param stream The stream of audio data. This should be formatted in LPCM encoded with 16 bits per sample and
* have a sample rate of 16 kHz. Additionally, the data should be in little endian format.
* @param audioFormat The format of the audio data located within the stream.
* @param keyWordObservers The observers to notify of keyword detections.
* @param keyWordDetectorStateObservers The observers to notify of state changes in the engine.
* @param keywordNotifier The object with which to notifiy observers of keyword detections.
* @param KeywordDetectorStateNotifier The object with which to notify observers of state changes in the engine.
* @param msToPushPerIteration The amount of data in milliseconds to push to the cloud at a time. This was the amount used by
* Sensory in example code.
*/
HIDKeywordDetector(
std::shared_ptr<AudioInputStream> stream,
std::unordered_set<std::shared_ptr<KeyWordObserverInterface>> keyWordObservers,
std::unordered_set<std::shared_ptr<KeyWordDetectorStateObserverInterface>> keyWordDetectorStateObservers,
const std::shared_ptr<acsdkKWDInterfaces::KeywordNotifierInterface> keywordNotifier,
const std::shared_ptr<acsdkKWDInterfaces::KeywordDetectorStateNotifierInterface> KeywordDetectorStateNotifier,
avsCommon::utils::AudioFormat audioFormat,
std::chrono::milliseconds msToPushPerIteration = std::chrono::milliseconds(10));

Expand Down
13 changes: 9 additions & 4 deletions applications/acsdkXMOSAdapter/HID/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@ pkg_check_modules(libevdev REQUIRED libevdev)
find_package(PkgConfig)
pkg_check_modules(libusb-1.0 REQUIRED libusb-1.0)

add_library(HID SHARED
add_library(HID
HIDKeywordDetector.cpp)

target_include_directories(HID PUBLIC
"${KWD_SOURCE_DIR}/include"
"${XMOS_SOURCE_DIR}/include"
"${HID_SOURCE_DIR}/../XMOS/include"
"${HID_SOURCE_DIR}/include")

target_link_libraries(HID KWD AVSCommon evdev usb-1.0)
target_link_libraries(HID
XMOS
acsdkKWDImplementations
acsdkKWDInterfaces
AVSCommon
evdev
usb-1.0)

# install target
asdk_install()
40 changes: 33 additions & 7 deletions applications/acsdkXMOSAdapter/HID/src/HIDKeywordDetector.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2021 XMOS LIMITED. This Software is subject to the terms of the
// Copyright (c) 2021-2022 XMOS LIMITED. This Software is subject to the terms of the
// XMOS Public License: Version 1
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
Expand All @@ -21,6 +21,7 @@
#include <chrono>
#include <dirent.h>

#include <acsdkKWDImplementations/KWDNotifierFactories.h>
#include <AVSCommon/Utils/Logger/Logger.h>

#include "HID/HIDKeywordDetector.h"
Expand Down Expand Up @@ -138,26 +139,52 @@ bool HIDKeywordDetector::openDevice() {
return true;
}

// Deprecated create method.
std::unique_ptr<HIDKeywordDetector> HIDKeywordDetector::create(
std::shared_ptr<AudioInputStream> stream,
avsCommon::utils::AudioFormat audioFormat,
std::unordered_set<std::shared_ptr<KeyWordObserverInterface>> keyWordObservers,
std::unordered_set<std::shared_ptr<KeyWordDetectorStateObserverInterface>> keyWordDetectorStateObservers,
std::chrono::milliseconds msToPushPerIteration) {
// Create Notifiers to be used instead of the observers.

This comment has been minimized.

Copy link
@mbanth

mbanth Jun 29, 2022

It looks like the creation of Notifiers and registration of Observers to Notifiers is duplicated in GPIOKeywordDetector and HIDKeywordDetector. Since this functionality does not differ between these two classes, there should be a way to perform it in only one place with no duplication. That place may be XMOSKeywordDetector or it may be that this functionality already exists in the underlying Amazon class that XMOSKeywordDetector is derived from.

auto keywordNotifier = acsdkKWDImplementations::KWDNotifierFactories::createKeywordNotifier();
for (auto kwObserver : keyWordObservers) {
keywordNotifier->addObserver(kwObserver);
}

auto keywordDetectorStateNotifier =
acsdkKWDImplementations::KWDNotifierFactories::createKeywordDetectorStateNotifier();
for (auto kwdStateObserver : keyWordDetectorStateObservers) {
keywordDetectorStateNotifier->addObserver(kwdStateObserver);
}

return create(
stream,
std::make_shared<avsCommon::utils::AudioFormat>(audioFormat),
keywordNotifier,
keywordDetectorStateNotifier,
msToPushPerIteration);
}

std::unique_ptr<HIDKeywordDetector> HIDKeywordDetector::create(
std::shared_ptr<avsCommon::avs::AudioInputStream> stream,
const std::shared_ptr<avsCommon::utils::AudioFormat>& audioFormat,
const std::shared_ptr<acsdkKWDInterfaces::KeywordNotifierInterface> keywordNotifier,
const std::shared_ptr<acsdkKWDInterfaces::KeywordDetectorStateNotifierInterface> keywordDetectorStateNotifier,
std::chrono::milliseconds msToPushPerIteration) {
if (!stream) {
ACSDK_ERROR(LX("createFailed").d("reason", "nullStream"));
return nullptr;
}

// TODO: ACSDK-249 - Investigate cpu usage of converting bytes between endianness and if it's not too much, do it.
if (isByteswappingRequired(audioFormat)) {
if (isByteswappingRequired(*audioFormat)) {

This comment has been minimized.

Copy link
@mbanth

mbanth Jun 29, 2022

Is this check really required here or can it be performed in the underlying XMOSKeywordDetector's create function or constructor? By putting it here, it is duplicated in both GPIOKeywordDetector and HIDKeywordDetector.

ACSDK_ERROR(LX("createFailed").d("reason", "endianMismatch"));
return nullptr;
}

std::unique_ptr<HIDKeywordDetector> detector(new HIDKeywordDetector(
stream, keyWordObservers, keyWordDetectorStateObservers, audioFormat));
stream, keywordNotifier, keywordDetectorStateNotifier, *audioFormat));

if (!detector->init()) {
ACSDK_ERROR(LX("createFailed").d("reason", "initDetectorFailed"));
Expand All @@ -169,17 +196,16 @@ std::unique_ptr<HIDKeywordDetector> HIDKeywordDetector::create(

HIDKeywordDetector::HIDKeywordDetector(
std::shared_ptr<AudioInputStream> stream,
std::unordered_set<std::shared_ptr<KeyWordObserverInterface>> keyWordObservers,
std::unordered_set<std::shared_ptr<KeyWordDetectorStateObserverInterface>> keyWordDetectorStateObservers,
std::shared_ptr<acsdkKWDInterfaces::KeywordNotifierInterface> keywordNotifier,
std::shared_ptr<acsdkKWDInterfaces::KeywordDetectorStateNotifierInterface> keywordDetectorStateNotifier,
avsCommon::utils::AudioFormat audioFormat,
std::chrono::milliseconds msToPushPerIteration) :
XMOSKeywordDetector(stream, keyWordObservers, keyWordDetectorStateObservers, audioFormat, msToPushPerIteration) {
XMOSKeywordDetector(stream, keywordNotifier, keywordDetectorStateNotifier, audioFormat, msToPushPerIteration) {
}

HIDKeywordDetector::~HIDKeywordDetector() {
}


bool HIDKeywordDetector::init() {
if (XMOSKeywordDetector::init()) {
m_detectionThread = std::thread(&HIDKeywordDetector::detectionLoop, this);
Expand Down
11 changes: 4 additions & 7 deletions applications/acsdkXMOSAdapter/XMOS/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
project(XMOS LANGUAGES CXX)

add_subdirectory("src")
include(${AVS_CMAKE_BUILD}/BuildDefaults.cmake)

# set(TARGET_KWD_LIB "acsdkXMOSAdapter" PARENT_SCOPE)

if(HID_KEY_WORD_DETECTOR)
add_subdirectory("HID")
endif()
if(GPIO_KEY_WORD_DETECTOR)
add_subdirectory("GPIO")
endif()
add_subdirectory("src")
Loading

0 comments on commit e5c63e4

Please sign in to comment.