Skip to content

Commit

Permalink
Try to fix SSML speech. Add SRAL_SetEngineParameter.
Browse files Browse the repository at this point in the history
  • Loading branch information
m1maker committed Oct 18, 2024
1 parent a1086d4 commit 4bae998
Show file tree
Hide file tree
Showing 15 changed files with 256 additions and 147 deletions.
11 changes: 11 additions & 0 deletions Bindings/Python/sral.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ def __del__(self):
def speak(self, text, interrupt=True):
return self.lib.SRAL_Speak(c_char_p(text.encode('utf-8')), c_bool(interrupt))

def speak_ssml(self, text, interrupt=True):
return self.lib.SRAL_SpeakSsml(c_char_p(text.encode('utf-8')), c_bool(interrupt))

def braille(self, text):
return self.lib.SRAL_Braille(c_char_p(text.encode('utf-8')))

Expand All @@ -46,6 +49,10 @@ def get_current_engine(self):
def get_engine_features(self, engine):
return self.lib.SRAL_GetEngineFeatures(c_int(engine))

def set_engine_parameter(self, engine, param, value):
return self.lib.SRAL_SetEngineParameter(c_int(engine), c_int(param), c_int(value))


def set_volume(self, value):
return self.lib.SRAL_SetVolume(c_uint64(value))

Expand Down Expand Up @@ -76,6 +83,10 @@ def set_voice(self, index):
def speak_ex(self, engine, text, interrupt=True):
return self.lib.SRAL_SpeakEx(c_int(engine), c_char_p(text.encode('utf-8')), c_bool(interrupt))

def speak_ssml_ex(self, engine, text, interrupt=True):
return self.lib.SRAL_SpeakSsmlEx(c_int(engine), c_char_p(text.encode('utf-8')), c_bool(interrupt))


def braille_ex(self, engine, text):
return self.lib.SRAL_BrailleEx(c_int(engine), c_char_p(text.encode('utf-8')))

Expand Down
59 changes: 54 additions & 5 deletions Include/SRAL.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,38 @@ extern "C" {
};

/**
* @brief Speak the given text.
* @param text A pointer to the text string to be spoken.
* @param interrupt A flag indicating whether to interrupt the current speech.
* @return true if speaking was successful, false otherwise.
*/
* @enum SRAL_EngineParams
* @brief Enumeration of engine parameters.
*/

enum SRAL_EngineParams {
SYMBOL_LEVEL,
SAPI_TRIM_THRESHOLD
};



/**
* @brief Speak the given text.
* @param text A pointer to the text string to be spoken.
* @param interrupt A flag indicating whether to interrupt the current speech.
* @return true if speaking was successful, false otherwise.
*/

SRAL_API bool SRAL_Speak(const char* text, bool interrupt);


/**
* @brief Speak the given text using SSML tags.
* @param SSML A pointer to the valid SSML string to be spoken.
* @param interrupt A flag indicating whether to interrupt the current speech.
* @return true if speaking was successful, false otherwise.
*/

SRAL_API bool SRAL_SpeakSsml(const char* ssml, bool interrupt);




/**
* @brief Output text to a Braille display.
Expand Down Expand Up @@ -129,6 +152,19 @@ extern "C" {

SRAL_API int SRAL_GetEngineFeatures(int engine);

/**
* @brief Set the parameter for the specified speech engine.
* @param engine The engine to set the param for.
* @param param The desired parameter.
* @param value The desired value.
* @return true if the parameter was set successfully, false otherwise.
*/

SRAL_API bool SRAL_SetEngineParameter(int engine, int param, int value);





/**
Expand Down Expand Up @@ -221,6 +257,19 @@ extern "C" {

SRAL_API bool SRAL_SpeakEx(int engine, const char* text, bool interrupt);

/**
* @brief Speak the given text with the specified engine and using SSML tags.
* @param engine The engine to use for speaking.
* @param ssml A pointer to the valid SSML string to be spoken.
* @param interrupt A flag indicating whether to interrupt the current speech.
* @return true if speaking was successful, false otherwise.
*/

SRAL_API bool SRAL_SpeakSsmlEx(int engine, const char* ssml, bool interrupt);




/**
* @brief Output text to a Braille display using the specified engine.
* @param engine The engine to use for Braille display output.
Expand Down
135 changes: 1 addition & 134 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,140 +7,7 @@ SRAL is a cross-platform library for output text using speech engines.
SRAL is supported on Windows, MacOS and Linux platforms.

## Header

## Enumerations

### `SRAL_Engines`
This enumeration defines the available speech engines supported by the SRAL library. The values are:
- `ENGINE_NONE = 0`: No engine selected.
- `ENGINE_NVDA = 2`: NVDA screen reader.
- `ENGINE_SAPI = 4`: Microsoft SAPI5 speech engine.
- `ENGINE_JAWS = 8`: Jaws screen reader.
- `ENGINE_SPEECH_DISPATCHER = 16`: Speech Dispatcher engine.
- `ENGINE_UIA = 32`: Microsoft UI Automation provider.
- `ENGINE_AV_SPEECH = 64`: AVSpeech engine.
- `ENGINE_NARRATOR = 128`: Windows Narrator to UIAutomation redirector, if running.



### `SRAL_SupportedFeatures`
This enumeration defines the features supported by the various speech engines. The values are:
- `SUPPORTS_SPEECH = 128`: The engine supports speech output.
- `SUPPORTS_BRAILLE = 256`: The engine supports Braille output.
- `SUPPORTS_SPEECH_RATE = 512`: The engine supports setting the speech rate.
- `SUPPORTS_SPEECH_VOLUME = 1024`: The engine supports setting the speech volume.
- `SUPPORTS_SELECT_VOICE = 2048`: The engine supports selecting a specific voice.
- `SUPPORTS_PAUSE_SPEECH = 4096`: The engine supports pause and resume speech.
- `SUPPORTS_SSML = 8192`: The engine supports the SSML tags for speak.


## Functions

### `SRAL_Speak(const char* text, bool interrupt)`
- **Description**: Speaks the given text.
- **Parameters**:
- `text`: A pointer to the text string to be spoken.
- `interrupt`: A flag indicating whether to interrupt the current speech.
- **Return Value**: `true` if speaking was successful, `false` otherwise.

### `SRAL_Braille(const char* text)`
- **Description**: Outputs the given text to a Braille display.
- **Parameters**:
- `text`: A pointer to the text string to be output in Braille.
- **Return Value**: `true` if Braille output was successful, `false` otherwise.

### `SRAL_Output(const char* text, bool interrupt)`
- **Description**: Outputs the given text using all currently supported speech engine methods.
- **Parameters**:
- `text`: A pointer to the text string to be output.
- `interrupt`: A flag indicating whether to interrupt the current speech.
- **Return Value**: `true` if output was successful, `false` otherwise.

### `SRAL_StopSpeech(void)`
- **Description**: Stops speech if it is active.
- **Return Value**: `true` if speech was stopped successfully, `false` otherwise.

### `SRAL_PauseSpeech(void)`
- **Description**: Pause speech if it is active and the current engine supports this.
- **Return Value**: `true` if speech was paused successfully, `false` otherwise.

### `SRAL_ResumeSpeech(void)`
- **Description**: Resume speech if it was paused.
- **Return Value**: `true` if speech was resumed successfully, `false` otherwise.


### `SRAL_GetCurrentEngine(void)`
- **Description**: Gets the current speech engine in use.
- **Return Value**: The identifier of the current speech engine defined by the `SRAL_Engines` enumeration.

### `SRAL_GetEngineFeatures(int engine)`
- **Description**: Gets the features supported by the specified engine.
- **Parameters**:
- `engine`: The identifier of the engine to query. Defaults to 0 (current engine).
- **Return Value**: An integer representing the features supported by the engine defined by the `SRAL_SupportedFeatures` enumeration.

### `SRAL_Initialize(int engines_exclude)`
- **Description**: Initializes the library and optionally excludes certain engines.
- **Parameters**:
- `engines_exclude`: A bitmask specifying engines to exclude from initialization. Defaults to 0 (include all).
- **Return Value**: `true` if initialization was successful, `false` otherwise.

### `SRAL_Uninitialize(void)`
- **Description**: Uninitializes the library, freeing resources.

### `SRAL_SetVolume(uint64_t value)`
- **Description**: Sets the speech volume level, if the current speech engine supports this.
- **Parameters**:
- `value`: The desired volume level.
- **Return Value**: `true` if the volume was set successfully, `false` otherwise.

### `SRAL_GetVolume(void)`
- **Description**: Gets the current speech volume level of the current speech engine.
- **Return Value**: The current volume level.

### `SRAL_SetRate(uint64_t value)`
- **Description**: Sets the speech rate, if the current engine supports this.
- **Parameters**:
- `value`: The desired speech rate.
- **Return Value**: `true` if the speech rate was set successfully, `false` otherwise.

### `SRAL_GetRate(void)`
- **Description**: Gets the current speech rate of the current speech engine.
- **Return Value**: The current speech rate.

### `SRAL_GetVoiceCount(void)`
- **Description**: Gets the count of available voices supported by the current speech engine.
- **Return Value**: The number of available voices.

### `SRAL_GetVoiceName(uint64_t index)`
- **Description**: Gets the name of a voice by its index, if the current speech engine supports this.
- **Parameters**:
- `index`: The index of a voice to get.
- **Return Value**: A pointer to the name of the voice.

### `SRAL_SetVoice(uint64_t index)`
- **Description**: Sets the currently selected voice by index, if the current speech engine supports this.
- **Parameters**:
- `index`: The index of a voice to set.
- **Return Value**: `true` if the voice was set successfully, `false` otherwise.

### Extended Functions

The library also provides extended functions to perform operations with specific speech engines. These functions follow the same naming convention as the regular functions, but with the addition of the `Ex` suffix. For example, `SRAL_SpeakEx`, `SRAL_BrailleEx`, `SRAL_OutputEx`, etc.

### `SRAL_IsInitialized(void)`
- **Description**: Checks if the library has been initialized.
- **Return Value**: `true` if the library is initialized, `false` otherwise.

### `SRAL_Delay(int time)`
- **Description**: Delayes the next speech or output operation by a given time.

### `SRAL_RegisterKeyboardHooks(void)`
- **Description**: Install speech interruption and pause keyboard hooks for speech engines other than screen readers, such as Microsoft SAPI 5 or SpeechDispatcher.
- **Return Value**: `true` if the hooks are successfully installed, `false` otherwise.

### `SRAL_UnregisterKeyboardHooks(void)`
- **Description**: Uninstall speech interruption and pause keyboard hooks.
See how to use SRAL in Include/SRAL.h

## Compilation
SRAL can build using CMake into two libraries, static and dynamic.
Expand Down
10 changes: 9 additions & 1 deletion SRC/AVSpeech.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ class AVSpeechSynthesizerWrapper;
class AVSpeech : public Engine {
public:
bool Speak(const char* text, bool interrupt)override;
bool SpeakSsml(const char* ssml, bool interrupt)override {
return false;
}
bool SetParameter(int param, int value)override {
return false;
}


bool Braille(const char* text)override { return false; }
bool StopSpeech()override;
bool PauseSpeech()override { return false; }
Expand All @@ -35,5 +43,5 @@ class AVSpeech : public Engine {
}

private:
AVSpeechSynthesizerWrapper* obj;
AVSpeechSynthesizerWrapper* obj = nullptr;
};
42 changes: 40 additions & 2 deletions SRC/Encoding.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#include "Encoding.h"
#include <vector>
#ifdef _WIN32
#include <windows.h>

#endif

bool UnicodeConvert(const std::string& input, std::wstring& output) {
#ifdef _WIN32
int size_needed = MultiByteToWideChar(CP_UTF8, 0, input.c_str(), -1, NULL, 0);
if (size_needed == 0) {
return false;
Expand All @@ -14,9 +16,11 @@ bool UnicodeConvert(const std::string& input, std::wstring& output) {
}
output.assign(wide_string.begin(), wide_string.end() - 1); // Remove null terminator
return true;
#endif
}

bool UnicodeConvert(const std::wstring& input, std::string& output) {
#ifdef _WIN32
int size_needed = WideCharToMultiByte(CP_UTF8, 0, input.c_str(), -1, NULL, 0, NULL, NULL);
if (size_needed == 0) {
return false;
Expand All @@ -27,4 +31,38 @@ bool UnicodeConvert(const std::wstring& input, std::string& output) {
}
output.assign(multi_byte_string.begin(), multi_byte_string.end() - 1); // Remove null terminator
return true;
}
#endif
}



void XmlEncode(std::string& data) {
std::string encoded;
encoded.reserve(data.size()); // Reserve space for efficiency

for (char c : data) {
switch (c) {
case '&':
encoded += "&amp;";
break;
case '<':
encoded += "&lt;";
break;
case '>':
encoded += "&gt;";
break;
case '"':
encoded += "&quot;";
break;
case '\'':
encoded += "&apos;";
break;
default:
encoded += c; // Copy the character as is
break;
}
}

data = encoded; // Update the original string with the encoded version
}

1 change: 1 addition & 0 deletions SRC/Encoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
#include <string>
bool UnicodeConvert(const std::string& input, std::wstring& output);
bool UnicodeConvert(const std::wstring& input, std::string& output);
void XmlEncode(std::string& data);
#endif // ENCODING_H
2 changes: 2 additions & 0 deletions SRC/Engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ enum KeyboardFlags {
class Engine {
public:
virtual bool Speak(const char* text, bool interrupt) = 0;
virtual bool SpeakSsml(const char* ssml, bool interrupt) = 0;

virtual bool Braille(const char* text) = 0;
virtual bool StopSpeech() = 0;
Expand All @@ -29,6 +30,7 @@ class Engine {
virtual const char* GetVoiceName(uint64_t index) = 0;
virtual bool SetVoice(uint64_t index) = 0;
virtual int GetKeyFlags() = 0;
virtual bool SetParameter(int param, int value) = 0;
bool paused;
};
#endif
7 changes: 7 additions & 0 deletions SRC/Jaws.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
class Jaws : public Engine {
public:
bool Speak(const char* text, bool interrupt)override;
bool SpeakSsml(const char* ssml, bool interrupt)override {
return false;
}
bool SetParameter(int param, int value)override {
return false;
}

bool Braille(const char* text)override;
bool StopSpeech()override;
bool PauseSpeech()override { return false; }
Expand Down
Loading

0 comments on commit 4bae998

Please sign in to comment.