Skip to content
This repository was archived by the owner on Jan 16, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
#config file required for SDK integration tests. Each user will configure this differently, so it is preferable that git not show this file as
#'untracked' when printing the status.
Integration/AuthDelegate.config
#config file with the secret client id (required for the device authorization)
tools/Install/config.json
#macOS specific files
.DS_Store
30 changes: 19 additions & 11 deletions MediaPlayer/GStreamerMediaPlayer/src/MediaPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -677,26 +677,34 @@ bool MediaPlayer::setupPipeline() {
}
}

std::string audioSinkElement;
std::string audioSinkDescription;
ConfigurationNode::getRoot()[MEDIAPLAYER_CONFIGURATION_ROOT_KEY].getString(
MEDIAPLAYER_AUDIO_SINK_KEY, &audioSinkElement, "autoaudiosink");
m_pipeline.audioSink = gst_element_factory_make(audioSinkElement.c_str(), "audio_sink");

/// If the sink is a fakesink, set sync to true so that it uses system clock for consuming the buffer
/// instead of the default behavior, which is to consume the buffer as fast as possible.
if (audioSinkElement == "fakesink") {
m_isFakeSink = true;
g_object_set(m_pipeline.audioSink, "sync", true, NULL);
}
MEDIAPLAYER_AUDIO_SINK_KEY, &audioSinkDescription, "autoaudiosink");
GError* error = NULL;
m_pipeline.audioSink = gst_parse_bin_from_description_full(
audioSinkDescription.c_str(),
TRUE,
NULL,
static_cast<GstParseFlags>(GST_PARSE_FLAG_FATAL_ERRORS | GST_PARSE_FLAG_NO_SINGLE_ELEMENT_BINS),
&error);

if (!m_pipeline.audioSink) {
ACSDK_ERROR(LX("setupPipelineFailed")
.d("name", RequiresShutdown::name())
.d("reason", "createAudioSinkElementFailed")
.d("audioSinkElement", audioSinkElement));
.d("errorMessage", error->message)
.d("audioSinkDescription", audioSinkDescription));
g_error_free(error);
return false;
}

/// If the sink is a fakesink, set sync to true so that it uses system clock for consuming the buffer
/// instead of the default behavior, which is to consume the buffer as fast as possible.
if (audioSinkDescription == "fakesink") {
m_isFakeSink = true;
g_object_set(m_pipeline.audioSink, "sync", true, NULL);
}

GstCaps* caps = gst_caps_new_empty_simple("audio/x-raw");
if (!caps) {
ACSDK_ERROR(
Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,17 @@ View the [C++ API References](https://alexa.github.io/avs-device-sdk/) for detai
### Security Requirements

All Alexa products must meet the [AVS Security Requirements](https://developer.amazon.com/en-US/docs/alexa/alexa-voice-service/avs-security-reqs.html). In addition, when building the AVS Device SDK, you are required to adhere to the [following security principles](https://developer.amazon.com/en-US/docs/alexa/avs-device-sdk/overview.html#security-requirements).

### This fork

Configure with the following command.
```
cmake ~/sdk-folder/sdk-source/avs-device-sdk -DGSTREAMER_MEDIA_PLAYER=ON -DPORTAUDIO=ON -DPKCS11=OFF -DPORTAUDIO_LIB_PATH=$PORTAUDIO_LIB_PATH -DPORTAUDIO_INCLUDE_DIR=/usr/include -DCMAKE_BUILD_TYPE=DEBUG -DPORCUPINE_KEY_WORD_DETECTOR=ON -DPORCUPINE_KEY_WORD_DETECTOR_LIB_PATH=/path/to/porcupine/libpv_porcupine.so -DPORCUPINE_KEY_WORD_DETECTOR_INCLUDE_DIR=/path/to/porcupine/include/
```

Before running, set these environment variables.
```
PORCUPINE_ACCESS_KEY
PORCUPINE_MODEL_PATH
PORCUPINE_KEYWORD_PATH
```
Original file line number Diff line number Diff line change
Expand Up @@ -1004,7 +1004,7 @@ void StackLowerThanAddress(const void* ptr, bool* result) {
// Make sure AddressSanitizer does not tamper with the stack here.
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
bool StackGrowsDown() {
int dummy;
int dummy = 0;
bool result;
StackLowerThanAddress(&dummy, &result);
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1004,7 +1004,7 @@ void StackLowerThanAddress(const void* ptr, bool* result) {
// Make sure AddressSanitizer does not tamper with the stack here.
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
bool StackGrowsDown() {
int dummy;
int dummy = 0;
bool result;
StackLowerThanAddress(&dummy, &result);
return result;
Expand Down
56 changes: 52 additions & 4 deletions cmakeBuild/cmake/KeywordDetector.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,17 @@ mark_as_dependent(AMAZONLITE_KEY_WORD_DETECTOR_MODEL_CPP_PATH AMAZONLITE_KEY_WOR
mark_as_dependent(AMAZONLITE_KEY_WORD_DETECTOR_LIB_PATH AMAZONLITE_KEY_WORD_DETECTOR)
mark_as_dependent(AMAZONLITE_KEY_WORD_DETECTOR_INCLUDE_DIR AMAZONLITE_KEY_WORD_DETECTOR)

if(NOT AMAZON_KEY_WORD_DETECTOR AND NOT AMAZONLITE_KEY_WORD_DETECTOR)
message("No keyword detector type specified, skipping build of keyword detector.")
return()
endif()
option(PORCUPINE_KEY_WORD_DETECTOR "Enable Porcupine keyword detector." OFF)
set(PORCUPINE_KEY_WORD_DETECTOR_LIB_PATH "" CACHE FILEPATH "Porcupine keyword detector library path.")
set(PORCUPINE_KEY_WORD_DETECTOR_INCLUDE_DIR "" CACHE PATH "Porcupine keyword detector include dir.")
mark_as_dependent(PORCUPINE_KEY_WORD_DETECTOR_LIB_PATH PORCUPINE_KEY_WORD_DETECTOR)
mark_as_dependent(PORCUPINE_KEY_WORD_DETECTOR_INCLUDE_DIR PORCUPINE_KEY_WORD_DETECTOR)

option(SNOWMAN_KEY_WORD_DETECTOR "Enable Snowman keyword detector." OFF)
set(SNOWMAN_LIB_PATH "" CACHE FILEPATH "Snowman keyword detector library path.")
set(SNOWMAN_INCLUDE_DIR "" CACHE PATH "Snowman keyword detector include dir.")
mark_as_dependent(SNOWMAN_LIB_PATH SNOWMAN_KEY_WORD_DETECTOR)
mark_as_dependent(SNOWMAN_INCLUDE_DIR SNOWMAN_KEY_WORD_DETECTOR)

if(AMAZON_KEY_WORD_DETECTOR)
message("Creating ${PROJECT_NAME} with keyword detector type: Amazon")
Expand All @@ -60,3 +67,44 @@ if(AMAZONLITE_KEY_WORD_DETECTOR)
add_definitions(-DKWD_AMAZONLITE)
set(KWD ON)
endif()

if(PORCUPINE_KEY_WORD_DETECTOR)
message("Creating ${PROJECT_NAME} with keyword detector type: Porcupine")
if(NOT PORCUPINE_KEY_WORD_DETECTOR_LIB_PATH)
message(FATAL_ERROR "Must pass library path of Porcupine KeywordDetector!")
endif()
if(NOT PORCUPINE_KEY_WORD_DETECTOR_INCLUDE_DIR)
message(FATAL_ERROR "Must pass include dir path of Porcupine KeywordDetector!")
endif()
add_definitions(-DKWD)
add_definitions(-DKWD_PORCUPINE)
set(KWD ON)
set(TARGET_KWD_LIB "${PORCUPINE_KEY_WORD_DETECTOR_LIB_PATH}")
set(TARGET_KWD_INCLUDE "${PORCUPINE_KEY_WORD_DETECTOR_INCLUDE_DIR}")
set(KWD_ADAPTER_REGISTRATION_FILE PorcupineKWDRegistration.cpp)
endif()

if(SNOWMAN_KEY_WORD_DETECTOR)
message("Creating ${PROJECT_NAME} with keyword detector type: Snowman")
if(NOT SNOWMAN_LIB_PATH)
message(FATAL_ERROR "Must pass Snowman's library path in SNOWMAN_LIB_PATH!")
endif()
if(NOT SNOWMAN_INCLUDE_DIR)
message(FATAL_ERROR "Must pass Snowman's include dir path in SNOWMAN_INCLUDE_DIR!")
endif()
add_definitions(-DKWD)
add_definitions(-DKWD_SNOWMAN)
set(KWD ON)
# TODO: Use PkgConfig to locate f77blas, cblas, lapack_atlas, atlas?
#set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH ON)
#find_package(PkgConfig)
#pkg_check_modules(...)
set(TARGET_KWD_LIB "${SNOWMAN_LIB_PATH}" f77blas cblas lapack_atlas atlas)
set(TARGET_KWD_INCLUDE "${SNOWMAN_INCLUDE_DIR}")
set(KWD_ADAPTER_REGISTRATION_FILE SnowmanKWDRegistration.cpp SnowboyWrapper.cpp)
endif()

if(NOT KWD)
message("No keyword detector type specified, skipping build of keyword detector.")
return()
endif()
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

#ifndef ACSDKKWDPROVIDER_KWDPROVIDER_SNOWBOYWRAPPER_H_
#define ACSDKKWDPROVIDER_KWDPROVIDER_SNOWBOYWRAPPER_H_

namespace alexaClientSDK {
namespace kwd {

/**
* The wrapper class for snowboy::SnowboyDetect class.
*
* Since the original API exposes std::string which will be ABI incompatible
* with GCC 5.1, this class replace them with const char*.
*
* We keep the actual instantiation in void* pointer in this header, to prevent
* from other files to include snowboy-detect.h file.
*
* Thanks to the community for the original idea:
* https://github.com/Kitt-AI/snowboy/issues/99
*/
class SnowboyWrapper {
public:
/**
* Call snowboy::SnowboyDetect::SnowboyDetect constructor
*
* @param resourceFilename for the first argument of the original API call.
* @param model for the second argument of the original API call.
*/
SnowboyWrapper(const char* resourceFilename, const char* model);

/**
* Destructor
*/
~SnowboyWrapper() = default;

/**
* Call snowboy::SnowboyDetect::RunDetection
*
* @param data for the first argument of the original API call.
* @param arrayLength for the second argument of the original API call.
* @param isEnd for the third argument of the original API call.
* @return the value of the original API call result.
*/
int RunDetection(const int16_t* const data, const int arrayLength, bool isEnd = false);

/**
* Call snowboy::SnowboyDetect::SetSensitivity
*
* @param sensitivity for the first argument of the original API call.
*/
void SetSensitivity(const char* sensitivity);

/**
* Call snowboy::SnowboyDetect::SetAudioGain
*
* @param audioGain for the first argument of the original API call.
*/
void SetAudioGain(const float audioGain);

/**
* Call snowboy::SnowboyDetect::ApplyFrontend
*
* @param applyFrontend for the first argument of the original API call.
*/
void ApplyFrontend(const bool applyFrontend);

/**
* Call snowboy::SnowboyDetect::SampleRate
*
* @return the value of the original API call result.
*/
int SampleRate() const;

/**
* Call snowboy::SnowboyDetect::NumChannels
*
* @return the value of the original API call result.
*/
int NumChannels() const;

/**
* Call snowboy::SnowboyDetect::BitsPerSample
*
* @return the value of the original API call result.
*/
int BitsPerSample() const;

private:
/// The actual Kitt.ai engine instantiation in pointer
void* m_snowboy;
};

} // namespace kwd
} // namespace alexaClientSDK

#endif // ACSDKKWDPROVIDER_KWDPROVIDER_SNOWBOYWRAPPER_H_
9 changes: 8 additions & 1 deletion shared/KWD/acsdkKWDProvider/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@ target_link_libraries(KeywordDetectorProvider AVSCommon acsdkKWDImplementations)
if(TARGET_KWD_LIB)
target_link_libraries(KeywordDetectorProvider ${TARGET_KWD_LIB})
else()
message(FATAL_ERROR "No KWD Target set")
message(FATAL_ERROR "No KWD Target lib set")
endif()

if(TARGET_KWD_INCLUDE)
target_include_directories(KeywordDetectorProvider PUBLIC
"${TARGET_KWD_INCLUDE}")
else()
message(FATAL_ERROR "No KWD Target include set")
endif()

# install target
Expand Down
Loading