Initial commit of picotts component for ESP-IDF.
Relevant PicoTTS source imported from https://github.com/ihuguet/picotts rather than submoduled, in an attempt to keep fetches small.
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
set(PICOTTS_SRCS
|
||||
picopr.c
|
||||
picosa.c
|
||||
picokpr.c
|
||||
picodata.c
|
||||
picokfst.c
|
||||
picodbg.c
|
||||
picokdt.c
|
||||
picoctrl.c
|
||||
picoktab.c
|
||||
picoacph.c
|
||||
picokdbg.c
|
||||
# picorsrc.c ### We use our custom esp_picorsrc.c instead
|
||||
picoos.c
|
||||
picospho.c
|
||||
picotok.c
|
||||
picosig.c
|
||||
picocep.c
|
||||
picofftsg.c
|
||||
picotrns.c
|
||||
picosig2.c
|
||||
picoextapi.c
|
||||
picopal.c
|
||||
picokpdf.c
|
||||
picobase.c
|
||||
picopam.c
|
||||
picowa.c
|
||||
picoklex.c
|
||||
picoapi.c
|
||||
picoknow.c
|
||||
)
|
||||
list(TRANSFORM PICOTTS_SRCS PREPEND "pico/lib/")
|
||||
|
||||
|
||||
idf_component_register(
|
||||
SRCS
|
||||
"esp_picotts.c"
|
||||
"esp_picorsrc.c"
|
||||
${PICOTTS_SRCS}
|
||||
INCLUDE_DIRS "include"
|
||||
PRIV_INCLUDE_DIRS "pico/lib"
|
||||
PRIV_REQUIRES "esp_partition"
|
||||
)
|
||||
|
||||
# Suppress warnings in the library source
|
||||
set_source_files_properties(
|
||||
${PICOTTS_SRCS}
|
||||
PROPERTIES COMPILE_FLAGS
|
||||
"-Wno-implicit-fallthrough -Wno-unused-but-set-variable -Wno-unused-function"
|
||||
)
|
||||
|
||||
# PicoTTS attempts to use exp() trickery which relies on a particular floating
|
||||
# point representation format, which seemingly does not hold on Xtensa. As
|
||||
# a workaround, we rename the picoos_quick_exp functin and provide our own
|
||||
# wrapper back to standard math.h exp() instead.
|
||||
set_source_files_properties(
|
||||
"pico/lib/picoos.c"
|
||||
PROPERTIES COMPILE_OPTIONS "-Dpicoos_quick_exp=picoos_quick_nope"
|
||||
)
|
||||
|
||||
# Embed the correct language resources under known names
|
||||
set(PICOTTS_TA_BIN "picotts_ta.bin")
|
||||
set(PICOTTS_SG_BIN "picotts_sg.bin")
|
||||
set(PICOTTS_LANG_DIR ${COMPONENT_DIR}/pico/lang)
|
||||
set(PICOTTS_TA_BIN_PATH ${CMAKE_CURRENT_BINARY_DIR}/${PICOTTS_TA_BIN})
|
||||
set(PICOTTS_SG_BIN_PATH ${CMAKE_CURRENT_BINARY_DIR}/${PICOTTS_SG_BIN})
|
||||
if(CONFIG_PICOTTS_LANGUAGE_EN_GB)
|
||||
set(PICOTTS_TA_SRC "en-GB_ta.bin")
|
||||
set(PICOTTS_SG_SRC "en-GB_kh0_sg.bin")
|
||||
elseif(CONFIG_PICOTTS_LANGUAGE_EN_US)
|
||||
set(PICOTTS_TA_SRC "en-US_ta.bin")
|
||||
set(PICOTTS_SG_SRC "en-US_lh0_sg.bin")
|
||||
elseif(CONFIG_PICOTTS_LANGUAGE_DE_DE)
|
||||
set(PICOTTS_TA_SRC "de-DE_ta.bin")
|
||||
set(PICOTTS_SG_SRC "de-DE_gl0_sg.bin")
|
||||
elseif(CONFIG_PICOTTS_LANGUAGE_ES_ES)
|
||||
set(PICOTTS_TA_SRC "es-ES_ta.bin")
|
||||
set(PICOTTS_SG_SRC "es-ES_zl0_sg.bin")
|
||||
elseif(CONFIG_PICOTTS_LANGUAGE_FR_FR)
|
||||
set(PICOTTS_TA_SRC "fr-FR_ta.bin")
|
||||
set(PICOTTS_SG_SRC "fr-FR_nk0_sg.bin")
|
||||
elseif(CONFIG_PICOTTS_LANGUAGE_IT_IT)
|
||||
set(PICOTTS_TA_SRC "it-IT_ta.bin")
|
||||
set(PICOTTS_SG_SRC "it-IT_cm0_sg.bin")
|
||||
endif()
|
||||
add_custom_command(OUTPUT ${PICOTTS_TA_BIN}
|
||||
COMMAND cp ${PICOTTS_LANG_DIR}/${PICOTTS_TA_SRC} ${PICOTTS_TA_BIN_PATH})
|
||||
add_custom_command(OUTPUT ${PICOTTS_SG_BIN}
|
||||
COMMAND cp ${PICOTTS_LANG_DIR}/${PICOTTS_SG_SRC} ${PICOTTS_SG_BIN_PATH})
|
||||
add_custom_target(picotts_ta_bin_gen DEPENDS ${PICOTTS_TA_BIN_PATH})
|
||||
add_custom_target(picotts_sg_bin_gen DEPENDS ${PICOTTS_SG_BIN_PATH})
|
||||
target_add_binary_data(
|
||||
${COMPONENT_LIB} ${PICOTTS_TA_BIN_PATH} BINARY DEPENDS picotts_ta_bin_gen)
|
||||
target_add_binary_data(
|
||||
${COMPONENT_LIB} ${PICOTTS_SG_BIN_PATH} BINARY DEPENDS picotts_sg_bin_gen)
|
||||
set_property(DIRECTORY "${COMPONENT_DIR}" APPEND PROPERTY
|
||||
ADDITIONAL_CLEAN_FILES ${PICOTTS_TA_BIN} ${PICOTTS_SG_BIN})
|
||||
@@ -0,0 +1,62 @@
|
||||
menu "Pico TTS"
|
||||
|
||||
choice PICOTTS_LANGUAGE
|
||||
prompt "Voice language"
|
||||
default PICOTTS_LANGUAGE_EN_GB
|
||||
|
||||
config PICOTTS_LANGUAGE_EN_GB
|
||||
bool "English (en-GB)"
|
||||
|
||||
config PICOTTS_LANGUAGE_EN_US
|
||||
bool "English (en-US)"
|
||||
|
||||
config PICOTTS_LANGUAGE_DE_DE
|
||||
bool "German (de-DE)"
|
||||
|
||||
config PICOTTS_LANGUAGE_ES_ES
|
||||
bool "Spanish (es-ES)"
|
||||
|
||||
config PICOTTS_LANGUAGE_FR_FR
|
||||
bool "French (fr-FR)"
|
||||
|
||||
config PICOTTS_LANGUAGE_IT_IT
|
||||
bool "Italian (it-IT)"
|
||||
|
||||
endchoice
|
||||
|
||||
choice PICOTTS_RESOURCE_MODE
|
||||
prompt "Resource storage mode"
|
||||
default PICOTTS_RESOURCE_MODE_EMBED
|
||||
|
||||
config PICOTTS_RESOURCE_MODE_EMBED
|
||||
bool "Embed into application binary"
|
||||
|
||||
config PICOTTS_RESOURCE_MODE_PARTITION
|
||||
bool "Load resources from raw partitions"
|
||||
|
||||
endchoice
|
||||
|
||||
config PICOTTS_TA_PARTITION
|
||||
string "TA resource partition name" if PICOTTS_RESOURCE_MODE_PARTITION
|
||||
default "picotts_ta"
|
||||
help
|
||||
Partition name where the Text Analysis (TA) resource blob is
|
||||
located. This needs to be flashed separately from the application.
|
||||
|
||||
config PICOTTS_SG_PARTITION
|
||||
string "SG resource partition name" if PICOTTS_RESOURCE_MODE_PARTITION
|
||||
default "picotts_sg"
|
||||
help
|
||||
Partition name where the Signal Generator (SG) resource blob is
|
||||
located. This needs to be flashed separately from the application.
|
||||
|
||||
config PICOTTS_INPUT_QUEUE_SIZE
|
||||
int "TTS input queue size"
|
||||
default 256
|
||||
help
|
||||
The size of the TTS input quueue used to transfer the text to be
|
||||
spoken over to the TTS engine. A larger size makes it less likely
|
||||
that the picotts_add() function will block, but of course has the
|
||||
downside of using up more memory.
|
||||
|
||||
endmenu
|
||||
@@ -0,0 +1,85 @@
|
||||
# PicoTTS
|
||||
|
||||
This component provides an ESP-IDF port of the popular PicoTTS Text-to-Speech engine. While Espressif provides an Chinese language TTS, to date there has been no support for other languages. PicoTTS fills this gap, and provides Text-To-Speech for the following languages:
|
||||
|
||||
- English (UK)
|
||||
- English (US)
|
||||
- German
|
||||
- French
|
||||
- Italian
|
||||
- Spanish
|
||||
|
||||
## Requirements
|
||||
|
||||
The Text-to-Speech engine is quite resource intensive. While the code size is only around 175KB, language resources occupy another 750-1400KB of flash depending on language, and the engine uses just over 1.1MB of RAM while initialised. As such an ESP32-S3 with sufficient amount of PSRAM and flash is a recommended target.
|
||||
|
||||
Note that while generating speech, the TTS task may be busy for quite some time and can easily trigger the IDF's watchdog. You may want to adjust the watchdog settings.
|
||||
|
||||
This component does not provide any board-specific audio support. The TTS engine generates 16bit/16KHz samples, and leaves it to the user to direct those to the correct audio device.
|
||||
|
||||
## Getting started
|
||||
|
||||
Using the PicoTTS component is straight forward. Effectively the steps are:
|
||||
|
||||
- Initialise the engine
|
||||
- Register a callback function to receive the speech samples
|
||||
- Send text to the engine
|
||||
- Eventually, shut down the engine
|
||||
|
||||
In code, this can look like:
|
||||
```
|
||||
#include "picotts.h"
|
||||
|
||||
#define TTS_TASK_PRIORITY 5
|
||||
#define TTS_CORE 1
|
||||
|
||||
void my_sample_cb(int16_t *buf, unsigned count)
|
||||
{
|
||||
esp_codec_dev_write(speaker_codec_dev, buf, count*2);
|
||||
}
|
||||
|
||||
if (picotts_init(TTS_TASK_PRIORITY, my_sample_cb, TTS_CORE))
|
||||
{
|
||||
static const msg[] = "Hello, world";
|
||||
picotts_add(msg, sizeof(msg)); // Include the \0 to tell TTS to go
|
||||
|
||||
// Do other stuff, or at least wait until the msg has been spoken
|
||||
|
||||
picotts_shutdown();
|
||||
}
|
||||
```
|
||||
|
||||
API documentation can be found in the [picotts.h](include/picotts.h) header file.
|
||||
|
||||
## Resource handling
|
||||
|
||||
The PicoTTS engine relies on two resource blobs, a Text Analysis (TA) resource and a Signal Generator (SG) resource. In upstream PicoTTS, these are loaded into RAM from files on disk. As RAM is a very precious resource on a microcontroller, this component has replaced the resource loading routines such that they can be accessed directly from memory-mapped flash instead. This reduces the RAM foot-print from 2.5MB down to 1.1MB.
|
||||
|
||||
There are two options on how to bundle the resource files onto flash. The default, and arguably the easiest, is to embed the resource files directly into the application binary. The one downside to this approach is that application size grows significantly, and may present an issue with firmware upgrades. You will definitely use a much larger application partition than usual. Alternatively, the resource files can be placed in dedicated flash partitions and accessed from there instead. These partitions have to be flashed independently from the application partition, but the advantage is that the language resources are no longer directly coupled to the application binary. Which approach is best will depend on the specific project circumstances.
|
||||
|
||||
|
||||
### Custom paritions for language resources
|
||||
|
||||
When this component is configured to load its language resources from partitions rather than having them directly embedded into the application binary itself, you will need to add partition entries to hold the Text Analysis (TA) and Signal Generator (SG) resources. Example entries for `partitions.csv`:
|
||||
|
||||
```
|
||||
picotts_ta, 0x40, 0x0, , 640K,
|
||||
picotts_sg, 0x40, 0x1, , 820K,
|
||||
```
|
||||
|
||||
You are free to use any valid partition type and subtype. This component loads
|
||||
purely by the partition name. The partition names may be changed via Kconfig if so desired.
|
||||
|
||||
The partition sizes may be shrunk to better match the language you're using. What's show here are the maximum partition sizes to fit any language bundle.
|
||||
|
||||
### Flashing language resources to partitions
|
||||
|
||||
When configured for loading language resources from partitions, the following commands can be used to flash them to the correct locations. These commands assume the partition names are "picotts\_ta" and "picotts\_sg", respectively.
|
||||
```
|
||||
parttool.py write_partition --partition-name picotts_ta --input build/esp-idf/picotts/picotts_ta.bin
|
||||
parttool.py write_partition --partition-name picotts_sg --input build/esp-idf/picotts/picotts_sg.bin
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
The [boot\_greeting](examples/boot_greeting/README.md) example is written for ESP-BOX and uses this component to issue a greeting upon boot.
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
/* Copyright (C) 2024 DiUS Computing Pty Ltd.
|
||||
* Licensed under the Apache 2.0 license.
|
||||
*
|
||||
* @author J Mattsson <jmattsson@dius.com.au>
|
||||
*/
|
||||
#include "picoapi.h"
|
||||
#include "picoapid.h"
|
||||
#include "picorsrc.h"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
// We need access to the internal definitions in order to implement an
|
||||
// alternative resource loader, hence this unorthodox include
|
||||
#include "pico/lib/picorsrc.c"
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
|
||||
static uint16_t esp_pico_load_pi_u16(const char *raw, unsigned offs)
|
||||
{
|
||||
uint16_t a = raw[offs];
|
||||
uint16_t b = raw[offs+1];
|
||||
return (b << 8 | a);
|
||||
}
|
||||
|
||||
static uint32_t esp_pico_load_pi_u32(const char *raw, unsigned offs)
|
||||
{
|
||||
uint32_t a = raw[offs];
|
||||
uint32_t b = raw[offs+1];
|
||||
uint32_t c = raw[offs+2];
|
||||
uint32_t d = raw[offs+3];
|
||||
return (d << 24 || c << 16 | b << 8 | a);
|
||||
}
|
||||
|
||||
|
||||
pico_status_t verify_svox_header(const char *raw)
|
||||
{
|
||||
const char marker[] = " (C) SVOX AG ";
|
||||
for (unsigned i = 0; i < sizeof(marker) -1; ++i)
|
||||
{
|
||||
if (raw[i] != (marker[i] - 0x20))
|
||||
return PICO_EXC_FILE_CORRUPT;
|
||||
}
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
pico_status_t esp_pico_loadResource(pico_System sys, const void *raw, pico_Resource *outResource)
|
||||
{
|
||||
picorsrc_Resource *resource = (picorsrc_Resource *)outResource;
|
||||
picorsrc_ResourceManager this = sys->rm;
|
||||
picorsrc_Resource res = picorsrc_newResource(this->common->mm);
|
||||
if (res == NULL)
|
||||
return picoos_emRaiseException(this->common->em, PICO_EXC_OUT_OF_MEM, NULL, NULL);
|
||||
|
||||
if (this->numResources >= PICO_MAX_NUM_RESOURCES)
|
||||
{
|
||||
picoos_deallocate(this->common->mm, (void *)&res);
|
||||
return picoos_emRaiseException(this->common->em, PICO_EXC_MAX_NUM_EXCEED,
|
||||
NULL, (picoos_char *)"no more than %i resources", PICO_MAX_NUM_RESOURCES);
|
||||
}
|
||||
|
||||
enum {
|
||||
SVOXHDR_OFFS = 0, // first 13 bytes = " (C) SVOX AG " downshifted by 0x20
|
||||
HEADER_LEN_OFFS = 13, // header length read as le u16 after that
|
||||
DATA_OFFS = HEADER_LEN_OFFS + 2,
|
||||
};
|
||||
pico_status_t status = verify_svox_header(raw + SVOXHDR_OFFS);
|
||||
if (status != PICO_OK)
|
||||
return picoos_emRaiseException(this->common->em, PICO_EXC_FILE_CORRUPT, NULL, NULL);
|
||||
unsigned hdrlen1 = esp_pico_load_pi_u16(raw, HEADER_LEN_OFFS);
|
||||
|
||||
const char *data = (const char *)raw + DATA_OFFS;
|
||||
|
||||
// This effectively covers the readHeader() step in picorsrc_loadResource()
|
||||
picoos_file_header_t header;
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
|
||||
status = picoos_hdrParseHeader(&header, data);
|
||||
#pragma GCC diagnostic pop
|
||||
data += hdrlen1;
|
||||
|
||||
if (status == PICO_OK &&
|
||||
isResourceLoaded(this, header.field[PICOOS_HEADER_NAME].value))
|
||||
status = PICO_WARN_RESOURCE_DOUBLE_LOAD;
|
||||
|
||||
uint32_t len = 0;
|
||||
if (status == PICO_OK)
|
||||
{
|
||||
len = esp_pico_load_pi_u32(data, 0);
|
||||
data += 4;
|
||||
|
||||
// We fib things here and /don't/ copy into a PICOOS_ALIGN_SIZE memory area,
|
||||
// but we get away with it due to the files data areas already being
|
||||
// align(4), and on the esp that's all we need.
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
|
||||
res->raw_mem = data;
|
||||
#pragma GCC diagnostic pop
|
||||
res->start = res->raw_mem;
|
||||
|
||||
// Note resource unique name
|
||||
int n = picoos_strlcpy(
|
||||
res->name, header.field[PICOOS_HEADER_NAME].value,
|
||||
PICORSRC_MAX_RSRC_NAME_SIZ);
|
||||
if (n > PICORSRC_MAX_RSRC_NAME_SIZ)
|
||||
{
|
||||
status = PICO_ERR_INDEX_OUT_OF_RANGE;
|
||||
picoos_emRaiseException(
|
||||
this->common->em, PICO_ERR_INDEX_OUT_OF_RANGE, NULL,
|
||||
(picoos_char *)"resource %s", res->name);
|
||||
}
|
||||
}
|
||||
|
||||
if (status == PICO_OK)
|
||||
{
|
||||
const uint8_t *ctype = header.field[PICOOS_HEADER_CONTENT_TYPE].value;
|
||||
if (picoos_strcmp(ctype, PICORSRC_FIELD_VALUE_TEXTANA) == 0)
|
||||
res->type = PICORSRC_TYPE_TEXTANA;
|
||||
else if (picoos_strcmp(ctype, PICORSRC_FIELD_VALUE_SIGGEN) == 0)
|
||||
res->type = PICORSRC_TYPE_SIGGEN;
|
||||
else
|
||||
res->type = PICORSRC_TYPE_OTHER;
|
||||
|
||||
// Create kb list from resource
|
||||
status = picorsrc_getKbList(this, res->start, len, &res->kbList);
|
||||
}
|
||||
|
||||
if (status == PICO_OK)
|
||||
{
|
||||
res->next = this->resources;
|
||||
this->resources = res;
|
||||
this->numResources++;
|
||||
*resource = res;
|
||||
}
|
||||
else {
|
||||
picorsrc_disposeResource(this->common->mm, &res);
|
||||
}
|
||||
return status;
|
||||
};
|
||||
|
||||
|
||||
pico_status_t esp_pico_unloadResource(pico_System sys, pico_Resource *inResource)
|
||||
{
|
||||
picorsrc_Resource *resource = (picorsrc_Resource *)inResource;
|
||||
picorsrc_ResourceManager this = sys->rm;
|
||||
|
||||
picorsrc_Resource r1, r2, rsrc;
|
||||
|
||||
if (resource == NULL)
|
||||
return PICO_ERR_NULLPTR_ACCESS;
|
||||
else
|
||||
rsrc = *resource;
|
||||
|
||||
if (rsrc->lockCount > 0)
|
||||
return PICO_EXC_RESOURCE_BUSY;
|
||||
|
||||
r1 = NULL;
|
||||
r2 = this->resources;
|
||||
while (r2 != NULL && r2 != rsrc) {
|
||||
r1 = r2;
|
||||
r2 = r2->next;
|
||||
}
|
||||
if (NULL == r1)
|
||||
this->resources = rsrc->next;
|
||||
else if (NULL == r2)
|
||||
return PICO_ERR_OTHER; /* didn't find resource in rm! */
|
||||
else
|
||||
r1->next = rsrc->next;
|
||||
|
||||
if (NULL != rsrc->kbList)
|
||||
picorsrc_releaseKbList(this, &rsrc->kbList);
|
||||
|
||||
picoos_deallocate(this->common->mm,(void **)resource);
|
||||
this->numResources--;
|
||||
|
||||
return PICO_OK;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef ESP_PICORSRC_H
|
||||
#define ESP_PICORSRC_H
|
||||
|
||||
#include "picorsrc.h"
|
||||
|
||||
pico_status_t esp_pico_loadResource(pico_System sys, const void *raw, pico_Resource *resource);
|
||||
|
||||
pico_status_t esp_pico_unloadResource(pico_System sys, pico_Resource *inResource);
|
||||
|
||||
#endif
|
||||
+344
@@ -0,0 +1,344 @@
|
||||
/* Copyright (C) 2024 DiUS Computing Pty Ltd.
|
||||
* Licensed under the Apache 2.0 license.
|
||||
*
|
||||
* @author J Mattsson <jmattsson@dius.com.au>
|
||||
*/
|
||||
#include "picotts.h"
|
||||
#include "picoapi.h"
|
||||
#include "picoapid.h"
|
||||
#include "esp_picorsrc.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_partition.h"
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/queue.h>
|
||||
#include <freertos/task.h>
|
||||
#include <freertos/semphr.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <math.h>
|
||||
|
||||
// Yep, that's 1.1MB needed by PicoTTS, not counting the resource files which
|
||||
// we access directly from flash.
|
||||
#define PICO_MEM_SIZE 1100000
|
||||
|
||||
#define PICOTASK_EXIT 0x0000001u
|
||||
|
||||
static picotts_output_fn outputCb;
|
||||
static picotts_error_notify_fn errorCb;
|
||||
|
||||
static SemaphoreHandle_t exitLock;
|
||||
static QueueHandle_t textQ;
|
||||
static TaskHandle_t picoTask;
|
||||
|
||||
static void *picoMemArea;
|
||||
|
||||
static pico_System picoSystem;
|
||||
static pico_Resource picoTaResource;
|
||||
static pico_Resource picoSgResource;
|
||||
static pico_Engine picoEngine;
|
||||
|
||||
static const pico_Char voiceName[] = "PicoVoice";
|
||||
static const char tag[] = "picotts";
|
||||
|
||||
|
||||
#ifdef CONFIG_PICOTTS_RESOURCE_MODE_EMBED
|
||||
// Embedded resources
|
||||
extern const char ta_bin_start[] asm("_binary_picotts_ta_bin_start");
|
||||
extern const char sg_bin_start[] asm("_binary_picotts_sg_bin_start");
|
||||
|
||||
#else
|
||||
|
||||
static esp_partition_mmap_handle_t taMmap;
|
||||
static esp_partition_mmap_handle_t sgMmap;
|
||||
|
||||
static const void *find_and_map_partition(
|
||||
const char *name, esp_partition_mmap_handle_t *handle)
|
||||
{
|
||||
const esp_partition_t *part =
|
||||
esp_partition_find_first(
|
||||
ESP_PARTITION_TYPE_ANY, ESP_PARTITION_SUBTYPE_ANY, name);
|
||||
if (!part)
|
||||
{
|
||||
ESP_LOGE(tag, "Partition '%s' not found", name);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
const void *ptr = 0;
|
||||
esp_err_t ret = esp_partition_mmap(
|
||||
part, 0, part->size, ESP_PARTITION_MMAP_DATA, &ptr, handle);
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(ret);
|
||||
ESP_LOGI(tag, "Partition '%s' mmap'd to %p", name, ptr);
|
||||
return (ret == ESP_OK) ? ptr : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void unmap_partitions(void)
|
||||
{
|
||||
if (taMmap)
|
||||
{
|
||||
esp_partition_munmap(taMmap);
|
||||
taMmap = 0;
|
||||
}
|
||||
if (sgMmap)
|
||||
{
|
||||
esp_partition_munmap(sgMmap);
|
||||
sgMmap = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static const void *find_ta_bin_start()
|
||||
{
|
||||
#ifdef CONFIG_PICOTTS_RESOURCE_MODE_EMBED
|
||||
return ta_bin_start;
|
||||
#else
|
||||
return find_and_map_partition(CONFIG_PICOTTS_TA_PARTITION, &taMmap);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static const void *find_sg_bin_start()
|
||||
{
|
||||
#ifdef CONFIG_PICOTTS_RESOURCE_MODE_EMBED
|
||||
return sg_bin_start;
|
||||
#else
|
||||
return find_and_map_partition(CONFIG_PICOTTS_SG_PARTITION, &sgMmap);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Use regular exp() function as the picotty hack doesn't work on Xtensa
|
||||
picoos_double picoos_quick_exp(const picoos_double y)
|
||||
{
|
||||
return exp(y);
|
||||
}
|
||||
|
||||
|
||||
static void esp_pico_err_print(const char *what, int code)
|
||||
{
|
||||
pico_Retstring msg;
|
||||
pico_getSystemStatusMessage(picoSystem, code, msg);
|
||||
ESP_LOGE(tag, "%s (%i): %s", what, code, msg);
|
||||
}
|
||||
|
||||
|
||||
static void esp_pico_run(void *)
|
||||
{
|
||||
ESP_LOGI(tag, "Task started");
|
||||
bool error = false;
|
||||
while(!error)
|
||||
{
|
||||
uint32_t flags;
|
||||
if (xTaskNotifyWait(0, ~0, &flags, 0) == pdPASS)
|
||||
{
|
||||
if (flags & PICOTASK_EXIT)
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t c;
|
||||
if (xQueuePeek(textQ, &c, pdMS_TO_TICKS(100) == pdPASS))
|
||||
{
|
||||
int16_t processed = 0;
|
||||
int ret = pico_putTextUtf8(picoEngine, &c, 1, &processed);
|
||||
if (ret)
|
||||
{
|
||||
esp_pico_err_print("Put text failed, stopping TTS", ret);
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (processed)
|
||||
xQueueReceive(textQ, &c, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int status;
|
||||
do {
|
||||
// Only PICO_DATA_PCM_16BIT is defined, so we don't propage the type info
|
||||
int16_t outbuf[128];
|
||||
int16_t bytes = 0, type = 0;
|
||||
status = pico_getData(picoEngine, outbuf, sizeof(outbuf), &bytes, &type);
|
||||
if (bytes > 0)
|
||||
outputCb(outbuf, bytes/2);
|
||||
} while (status == PICO_STEP_BUSY);
|
||||
if (status != PICO_STEP_IDLE)
|
||||
{
|
||||
esp_pico_err_print("Get data failed, stopping TTS", status);
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
ESP_LOGI(tag, "Exiting task");
|
||||
xSemaphoreGive(exitLock);
|
||||
vTaskDelete(NULL);
|
||||
|
||||
if (error && errorCb)
|
||||
errorCb();
|
||||
}
|
||||
|
||||
|
||||
static void esp_pico_cleanup(void)
|
||||
{
|
||||
if (picoTask)
|
||||
{
|
||||
xTaskNotify(picoTask, PICOTASK_EXIT, eSetBits);
|
||||
xSemaphoreTake(exitLock, portMAX_DELAY);
|
||||
picoTask = NULL;
|
||||
}
|
||||
|
||||
if (picoEngine)
|
||||
{
|
||||
pico_disposeEngine(picoSystem, &picoEngine);
|
||||
pico_releaseVoiceDefinition(picoSystem, voiceName);
|
||||
picoEngine = NULL;
|
||||
}
|
||||
|
||||
if (picoSgResource)
|
||||
{
|
||||
esp_pico_unloadResource(picoSystem, &picoSgResource);
|
||||
picoSgResource = NULL;
|
||||
}
|
||||
|
||||
if (picoTaResource)
|
||||
{
|
||||
esp_pico_unloadResource(picoSystem, &picoTaResource);
|
||||
picoTaResource = NULL;
|
||||
}
|
||||
|
||||
if (picoSystem)
|
||||
{
|
||||
pico_terminate(&picoSystem);
|
||||
picoSystem = NULL;
|
||||
}
|
||||
|
||||
free(picoMemArea);
|
||||
picoMemArea = NULL;
|
||||
|
||||
if (textQ)
|
||||
{
|
||||
vQueueDelete(textQ);
|
||||
textQ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool picotts_init(unsigned prio, picotts_output_fn cb, int core)
|
||||
{
|
||||
if (!exitLock)
|
||||
exitLock = xSemaphoreCreateBinary();
|
||||
|
||||
outputCb = cb;
|
||||
|
||||
if (picoMemArea)
|
||||
{
|
||||
ESP_LOGE(tag, "already initialized");
|
||||
return false;
|
||||
}
|
||||
picoMemArea = malloc(PICO_MEM_SIZE);
|
||||
if (!picoMemArea)
|
||||
{
|
||||
ESP_LOGE(tag, "insufficient memory to initialize picotts");
|
||||
return false;
|
||||
}
|
||||
|
||||
#define PICO_INIT_CHECK(msg) \
|
||||
if (ret != 0) \
|
||||
{ \
|
||||
esp_pico_err_print(msg, ret); \
|
||||
esp_pico_cleanup(); \
|
||||
return false; \
|
||||
}
|
||||
|
||||
int ret = pico_initialize(picoMemArea, PICO_MEM_SIZE, &picoSystem);
|
||||
PICO_INIT_CHECK("init failed");
|
||||
|
||||
const void *ta = find_ta_bin_start();
|
||||
if (!ta)
|
||||
{
|
||||
ESP_LOGE(tag, "Unable to find text analysis resource");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
ESP_LOGI(tag, "Loading text analysis resource from %p", ta);
|
||||
|
||||
ret = esp_pico_loadResource(picoSystem, ta, &picoTaResource);
|
||||
PICO_INIT_CHECK("Text analysis load failed");
|
||||
|
||||
const void *sg = find_sg_bin_start();
|
||||
if (!sg)
|
||||
{
|
||||
ESP_LOGE(tag, "Unable to find signal generator resource");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
ESP_LOGI(tag, "Loading signal generator resource from %p", sg);
|
||||
|
||||
ret = esp_pico_loadResource(picoSystem, sg, &picoSgResource);
|
||||
PICO_INIT_CHECK("Signal generator load failed");
|
||||
|
||||
ret = pico_createVoiceDefinition(picoSystem, voiceName);
|
||||
PICO_INIT_CHECK("Voice creation failed");
|
||||
|
||||
pico_Retstring str;
|
||||
|
||||
ret = pico_getResourceName(picoSystem, picoTaResource, str);
|
||||
PICO_INIT_CHECK("TA resource name error");
|
||||
ret = pico_addResourceToVoiceDefinition(
|
||||
picoSystem, voiceName, (const pico_Char *)str);
|
||||
PICO_INIT_CHECK("TA resource add failed");
|
||||
|
||||
ret = pico_getResourceName(picoSystem, picoSgResource, str);
|
||||
PICO_INIT_CHECK("SG resource name error");
|
||||
ret = pico_addResourceToVoiceDefinition(
|
||||
picoSystem, voiceName, (const pico_Char *)str);
|
||||
PICO_INIT_CHECK("SG resource add failed");
|
||||
|
||||
ret = pico_newEngine(picoSystem, voiceName, &picoEngine);
|
||||
PICO_INIT_CHECK("Engine creation failed");
|
||||
|
||||
#undef PICO_INIT_CHECK
|
||||
|
||||
textQ = xQueueCreate(CONFIG_PICOTTS_INPUT_QUEUE_SIZE, sizeof(char));
|
||||
if (!textQ)
|
||||
{
|
||||
ESP_LOGE(tag, "Failed to create input queue");
|
||||
esp_pico_cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xTaskCreatePinnedToCore(esp_pico_run, "picotts", 8192, NULL,
|
||||
prio, &picoTask, core == -1 ? tskNO_AFFINITY : core)
|
||||
!= pdPASS)
|
||||
{
|
||||
ESP_LOGE(tag, "Failed to create task");
|
||||
esp_pico_cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void picotts_add(const char *text, unsigned len)
|
||||
{
|
||||
while(len--)
|
||||
xQueueSendToBack(textQ, text++, portMAX_DELAY);
|
||||
}
|
||||
|
||||
|
||||
void picotts_shutdown(void)
|
||||
{
|
||||
esp_pico_cleanup();
|
||||
|
||||
#if CONFIG_PICOTTS_RESOURCE_MODE_PARTITION
|
||||
unmap_partitions();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void picotts_set_error_notify(picotts_error_notify_fn cb)
|
||||
{
|
||||
errorCb = cb;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
build
|
||||
sdkconfig
|
||||
sdkconfig.old
|
||||
dependencies.lock
|
||||
managed_components
|
||||
@@ -0,0 +1,3 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(boot_greeting)
|
||||
@@ -0,0 +1,29 @@
|
||||
# PicoTTS Boot Greeting Example
|
||||
|
||||
This example is for ESP-BOX, and demonstrates how to initialise and use the PicoTTS component.
|
||||
|
||||
When booting, the ESP-BOX will issue a spoken greeting.
|
||||
|
||||
The example uses a minimal Board Support Package (BSP) derived from the official Espressif [esp-bsp repo](https://github.com/espressif/esp-bsp/tree/master/bsp/esp-box). Porting the example to other boards is hopefully pretty easy.
|
||||
|
||||
## Configuration
|
||||
|
||||
The greeting message can be customised via Kconfig, as can the volume.
|
||||
|
||||
## Building and flashing
|
||||
|
||||
The default picotts component configuration is to embed the language resource files into the binary, so to build and flash you only need to:
|
||||
|
||||
```
|
||||
idf.py build
|
||||
idf.py flash
|
||||
```
|
||||
|
||||
The partition table in this example also makes allowance for having the picotts language resource files stored in separate partitions, but if switching to that option you will additionally need to run:
|
||||
|
||||
```
|
||||
parttool.py write_partition --partition-name picotts_ta --input build/esp-idf/picotts/picotts_ta.bin
|
||||
parttool.py write_partition --partition-name picotts_sg --input build/esp-idf/picotts/picotts_sg.bin
|
||||
```
|
||||
|
||||
As usual, the console log can be accessed with `idf.py monitor`.
|
||||
@@ -0,0 +1,6 @@
|
||||
idf_component_register(
|
||||
SRCS
|
||||
"boot_greeting.c"
|
||||
"bsp/esp-box.c"
|
||||
INCLUDE_DIRS ""
|
||||
)
|
||||
@@ -0,0 +1,48 @@
|
||||
menu "Board Support Package(ESP-BOX)"
|
||||
|
||||
config BSP_ERROR_CHECK
|
||||
bool "Enable error check in BSP"
|
||||
default y
|
||||
help
|
||||
Error check assert the application before returning the error code.
|
||||
|
||||
menu "I2C"
|
||||
config BSP_I2C_NUM
|
||||
int "I2C peripheral index"
|
||||
default 1
|
||||
range 0 1
|
||||
help
|
||||
ESP32S3 has two I2C peripherals, pick the one you want to use.
|
||||
|
||||
config BSP_I2C_FAST_MODE
|
||||
bool "Enable I2C fast mode"
|
||||
default y
|
||||
help
|
||||
I2C has two speed modes: normal (100kHz) and fast (400kHz).
|
||||
|
||||
config BSP_I2C_CLK_SPEED_HZ
|
||||
int
|
||||
default 400000 if BSP_I2C_FAST_MODE
|
||||
default 100000
|
||||
endmenu
|
||||
|
||||
config BSP_I2S_NUM
|
||||
int "I2S peripheral index"
|
||||
default 1
|
||||
range 0 1
|
||||
help
|
||||
ESP32S3 has two I2S peripherals, pick the one you want to use.
|
||||
endmenu
|
||||
|
||||
menu "Boot greeting"
|
||||
|
||||
config BOOT_GREETING_MSG
|
||||
string "Message to speak on startup"
|
||||
default "ESP now online"
|
||||
|
||||
config BOOT_GREETING_VOLUME
|
||||
int "Speaker volume (%)"
|
||||
default 50
|
||||
range 0 100
|
||||
|
||||
endmenu
|
||||
@@ -0,0 +1,48 @@
|
||||
#include "picotts.h"
|
||||
#include "bsp/esp-bsp.h"
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TTS_CORE 1
|
||||
|
||||
const char greeting[] = CONFIG_BOOT_GREETING_MSG;
|
||||
|
||||
static esp_codec_dev_handle_t spk_codec;
|
||||
|
||||
static void on_samples(int16_t *buf, unsigned count)
|
||||
{
|
||||
esp_codec_dev_write(spk_codec, buf, count*2);
|
||||
}
|
||||
|
||||
|
||||
void app_main()
|
||||
{
|
||||
ESP_ERROR_CHECK(bsp_i2c_init());
|
||||
|
||||
ESP_ERROR_CHECK(bsp_audio_init(NULL));
|
||||
|
||||
spk_codec = bsp_audio_codec_speaker_init();
|
||||
assert(spk_codec);
|
||||
esp_codec_dev_set_out_vol(spk_codec, CONFIG_BOOT_GREETING_VOLUME);
|
||||
esp_codec_dev_sample_info_t fs = {
|
||||
.sample_rate = PICOTTS_SAMPLE_FREQ_HZ,
|
||||
.channel = 1,
|
||||
.bits_per_sample = PICOTTS_SAMPLE_BITS,
|
||||
};
|
||||
esp_codec_dev_open(spk_codec, &fs);
|
||||
|
||||
unsigned prio = uxTaskPriorityGet(NULL);
|
||||
if (picotts_init(prio, on_samples, TTS_CORE))
|
||||
{
|
||||
picotts_add(greeting, sizeof(greeting));
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(10000));
|
||||
|
||||
picotts_shutdown();
|
||||
}
|
||||
else
|
||||
printf("Failed to initialise TTS\n");
|
||||
|
||||
esp_codec_dev_close(spk_codec);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_check.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Assert on error, if selected in menuconfig. Otherwise return error code. */
|
||||
#if CONFIG_BSP_ERROR_CHECK
|
||||
#define BSP_ERROR_CHECK_RETURN_ERR(x) ESP_ERROR_CHECK(x)
|
||||
#define BSP_ERROR_CHECK_RETURN_NULL(x) ESP_ERROR_CHECK(x)
|
||||
#define BSP_ERROR_CHECK(x, ret) ESP_ERROR_CHECK(x)
|
||||
#define BSP_NULL_CHECK(x, ret) assert(x)
|
||||
#define BSP_NULL_CHECK_GOTO(x, goto_tag) assert(x)
|
||||
#else
|
||||
#define BSP_ERROR_CHECK_RETURN_ERR(x) do { \
|
||||
esp_err_t err_rc_ = (x); \
|
||||
if (unlikely(err_rc_ != ESP_OK)) { \
|
||||
return err_rc_; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define BSP_ERROR_CHECK_RETURN_NULL(x) do { \
|
||||
if (unlikely((x) != ESP_OK)) { \
|
||||
return NULL; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define BSP_NULL_CHECK(x, ret) do { \
|
||||
if ((x) == NULL) { \
|
||||
return ret; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define BSP_ERROR_CHECK(x, ret) do { \
|
||||
if (unlikely((x) != ESP_OK)) { \
|
||||
return ret; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define BSP_NULL_CHECK_GOTO(x, goto_tag) do { \
|
||||
if ((x) == NULL) { \
|
||||
goto goto_tag; \
|
||||
} \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Cut-down BSP file from original from Espressif's esp-bsp repo.
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "esp-box.h"
|
||||
#include "esp_err.h"
|
||||
#include "bsp_err_check.h"
|
||||
#include "esp_codec_dev_defaults.h"
|
||||
|
||||
static const char *TAG = "ESP-BOX";
|
||||
|
||||
static bool i2c_initialized = false;
|
||||
static i2s_chan_handle_t i2s_tx_chan = NULL;
|
||||
static i2s_chan_handle_t i2s_rx_chan = NULL;
|
||||
static const audio_codec_data_if_t *i2s_data_if = NULL;
|
||||
|
||||
|
||||
|
||||
/* Can be used for i2s_std_gpio_config_t and/or i2s_std_config_t initialization */
|
||||
#define BSP_I2S_GPIO_CFG \
|
||||
{ \
|
||||
.mclk = BSP_I2S_MCLK, \
|
||||
.bclk = BSP_I2S_SCLK, \
|
||||
.ws = BSP_I2S_LCLK, \
|
||||
.dout = BSP_I2S_DOUT, \
|
||||
.din = BSP_I2S_DSIN, \
|
||||
.invert_flags = { \
|
||||
.mclk_inv = false, \
|
||||
.bclk_inv = false, \
|
||||
.ws_inv = false, \
|
||||
}, \
|
||||
}
|
||||
|
||||
/* This configuration is used by default in bsp_audio_init() */
|
||||
#define BSP_I2S_DUPLEX_MONO_CFG(_sample_rate) \
|
||||
{ \
|
||||
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(_sample_rate), \
|
||||
.slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO), \
|
||||
.gpio_cfg = BSP_I2S_GPIO_CFG, \
|
||||
}
|
||||
|
||||
|
||||
esp_err_t bsp_audio_init(const i2s_std_config_t *i2s_config)
|
||||
{
|
||||
esp_err_t ret = ESP_FAIL;
|
||||
if (i2s_tx_chan && i2s_rx_chan) {
|
||||
/* Audio was initialized before */
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Setup I2S peripheral */
|
||||
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(CONFIG_BSP_I2S_NUM, I2S_ROLE_MASTER);
|
||||
chan_cfg.auto_clear = true; // Auto clear the legacy data in the DMA buffer
|
||||
BSP_ERROR_CHECK_RETURN_ERR(i2s_new_channel(&chan_cfg, &i2s_tx_chan, &i2s_rx_chan));
|
||||
|
||||
/* Setup I2S channels */
|
||||
const i2s_std_config_t std_cfg_default = BSP_I2S_DUPLEX_MONO_CFG(22050);
|
||||
const i2s_std_config_t *p_i2s_cfg = &std_cfg_default;
|
||||
if (i2s_config != NULL) {
|
||||
p_i2s_cfg = i2s_config;
|
||||
}
|
||||
|
||||
if (i2s_tx_chan != NULL) {
|
||||
ESP_GOTO_ON_ERROR(i2s_channel_init_std_mode(i2s_tx_chan, p_i2s_cfg), err, TAG, "I2S channel initialization failed");
|
||||
ESP_GOTO_ON_ERROR(i2s_channel_enable(i2s_tx_chan), err, TAG, "I2S enabling failed");
|
||||
}
|
||||
if (i2s_rx_chan != NULL) {
|
||||
ESP_GOTO_ON_ERROR(i2s_channel_init_std_mode(i2s_rx_chan, p_i2s_cfg), err, TAG, "I2S channel initialization failed");
|
||||
ESP_GOTO_ON_ERROR(i2s_channel_enable(i2s_rx_chan), err, TAG, "I2S enabling failed");
|
||||
}
|
||||
|
||||
audio_codec_i2s_cfg_t i2s_cfg = {
|
||||
.port = CONFIG_BSP_I2S_NUM,
|
||||
.rx_handle = i2s_rx_chan,
|
||||
.tx_handle = i2s_tx_chan,
|
||||
};
|
||||
i2s_data_if = audio_codec_new_i2s_data(&i2s_cfg);
|
||||
BSP_NULL_CHECK_GOTO(i2s_data_if, err);
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
err:
|
||||
if (i2s_tx_chan) {
|
||||
i2s_del_channel(i2s_tx_chan);
|
||||
}
|
||||
if (i2s_rx_chan) {
|
||||
i2s_del_channel(i2s_rx_chan);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const audio_codec_data_if_t *bsp_audio_get_codec_itf(void)
|
||||
{
|
||||
return i2s_data_if;
|
||||
}
|
||||
|
||||
esp_err_t bsp_i2c_init(void)
|
||||
{
|
||||
/* I2C was initialized before */
|
||||
if (i2c_initialized) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
const i2c_config_t i2c_conf = {
|
||||
.mode = I2C_MODE_MASTER,
|
||||
.sda_io_num = BSP_I2C_SDA,
|
||||
.sda_pullup_en = GPIO_PULLUP_DISABLE,
|
||||
.scl_io_num = BSP_I2C_SCL,
|
||||
.scl_pullup_en = GPIO_PULLUP_DISABLE,
|
||||
.master.clk_speed = CONFIG_BSP_I2C_CLK_SPEED_HZ
|
||||
};
|
||||
BSP_ERROR_CHECK_RETURN_ERR(i2c_param_config(BSP_I2C_NUM, &i2c_conf));
|
||||
BSP_ERROR_CHECK_RETURN_ERR(i2c_driver_install(BSP_I2C_NUM, i2c_conf.mode, 0, 0, 0));
|
||||
|
||||
i2c_initialized = true;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
esp_codec_dev_handle_t bsp_audio_codec_speaker_init(void)
|
||||
{
|
||||
const audio_codec_data_if_t *i2s_data_if = bsp_audio_get_codec_itf();
|
||||
if (i2s_data_if == NULL) {
|
||||
/* Initilize I2C */
|
||||
BSP_ERROR_CHECK_RETURN_NULL(bsp_i2c_init());
|
||||
/* Configure I2S peripheral and Power Amplifier */
|
||||
BSP_ERROR_CHECK_RETURN_NULL(bsp_audio_init(NULL));
|
||||
i2s_data_if = bsp_audio_get_codec_itf();
|
||||
}
|
||||
assert(i2s_data_if);
|
||||
|
||||
const audio_codec_gpio_if_t *gpio_if = audio_codec_new_gpio();
|
||||
|
||||
audio_codec_i2c_cfg_t i2c_cfg = {
|
||||
.port = BSP_I2C_NUM,
|
||||
.addr = ES8311_CODEC_DEFAULT_ADDR,
|
||||
};
|
||||
const audio_codec_ctrl_if_t *i2c_ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg);
|
||||
BSP_NULL_CHECK(i2c_ctrl_if, NULL);
|
||||
|
||||
esp_codec_dev_hw_gain_t gain = {
|
||||
.pa_voltage = 5.0,
|
||||
.codec_dac_voltage = 3.3,
|
||||
};
|
||||
|
||||
es8311_codec_cfg_t es8311_cfg = {
|
||||
.ctrl_if = i2c_ctrl_if,
|
||||
.gpio_if = gpio_if,
|
||||
.codec_mode = ESP_CODEC_DEV_WORK_MODE_DAC,
|
||||
.pa_pin = BSP_POWER_AMP_IO,
|
||||
.pa_reverted = false,
|
||||
.master_mode = false,
|
||||
.use_mclk = true,
|
||||
.digital_mic = false,
|
||||
.invert_mclk = false,
|
||||
.invert_sclk = false,
|
||||
.hw_gain = gain,
|
||||
};
|
||||
const audio_codec_if_t *es8311_dev = es8311_codec_new(&es8311_cfg);
|
||||
BSP_NULL_CHECK(es8311_dev, NULL);
|
||||
|
||||
esp_codec_dev_cfg_t codec_dev_cfg = {
|
||||
.dev_type = ESP_CODEC_DEV_TYPE_OUT,
|
||||
.codec_if = es8311_dev,
|
||||
.data_if = i2s_data_if,
|
||||
};
|
||||
return esp_codec_dev_new(&codec_dev_cfg);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef ESP_BOX_H
|
||||
#define ESP_BOX_H
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "driver/i2c.h"
|
||||
#include "driver/i2s_std.h"
|
||||
#include "esp_codec_dev.h"
|
||||
|
||||
#define BSP_I2C_SCL (GPIO_NUM_18)
|
||||
#define BSP_I2C_SDA (GPIO_NUM_8)
|
||||
|
||||
#define BSP_I2S_SCLK (GPIO_NUM_17)
|
||||
#define BSP_I2S_MCLK (GPIO_NUM_2)
|
||||
#define BSP_I2S_LCLK (GPIO_NUM_47)
|
||||
#define BSP_I2S_DOUT (GPIO_NUM_15) // To Codec ES8311
|
||||
#define BSP_I2S_DSIN (GPIO_NUM_16) // From ADC ES7210
|
||||
#define BSP_POWER_AMP_IO (GPIO_NUM_46)
|
||||
#define BSP_MUTE_STATUS (GPIO_NUM_1)
|
||||
|
||||
#define BSP_I2C_NUM CONFIG_BSP_I2C_NUM
|
||||
|
||||
esp_err_t bsp_i2c_init(void);
|
||||
esp_err_t bsp_audio_init(const i2s_std_config_t *i2s_config);
|
||||
esp_codec_dev_handle_t bsp_audio_codec_speaker_init(void);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,2 @@
|
||||
#pragma once
|
||||
#include "esp-box.h"
|
||||
@@ -0,0 +1,5 @@
|
||||
dependencies:
|
||||
espressif/esp_codec_dev: "~1.0.0"
|
||||
dius/picotts:
|
||||
version: "~1.0.0"
|
||||
override_path: "../../../"
|
||||
@@ -0,0 +1,7 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, , 0x6000,
|
||||
phy_init, data, phy, , 0x1000,
|
||||
factory, app, factory, , 2500K,
|
||||
picotts_ta, 0x40, 0x0, , 640K,
|
||||
picotts_sg, 0x40, 0x1, , 820K,
|
||||
|
@@ -0,0 +1,22 @@
|
||||
# This file was generated using idf.py save-defconfig. It can be edited manually.
|
||||
# Espressif IoT Development Framework (ESP-IDF) 5.3.0 Project Minimal Configuration
|
||||
#
|
||||
CONFIG_IDF_TARGET="esp32s3"
|
||||
CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16
|
||||
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_SPIRAM=y
|
||||
CONFIG_SPIRAM_MODE_OCT=y
|
||||
CONFIG_SPIRAM_SPEED_80M=y
|
||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
||||
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=n
|
||||
CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y
|
||||
CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744
|
||||
CONFIG_LWIP_TCP_WND_DEFAULT=5744
|
||||
CONFIG_CODEC_ES7243_SUPPORT=n
|
||||
CONFIG_CODEC_ES7243E_SUPPORT=n
|
||||
CONFIG_CODEC_ES8156_SUPPORT=n
|
||||
CONFIG_CODEC_ES8374_SUPPORT=n
|
||||
CONFIG_CODEC_ES8388_SUPPORT=n
|
||||
CONFIG_CODEC_TAS5805M_SUPPORT=n
|
||||
@@ -0,0 +1,6 @@
|
||||
version: "1.0.0"
|
||||
description: "PicoTTS Text-to-Speech engine"
|
||||
license: "Apache-2.0"
|
||||
maintainers:
|
||||
- J Mattsson <jmattsson@dius.com.au>
|
||||
url: "https://github.com/DiUS/esp-picotts"
|
||||
@@ -0,0 +1,54 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define PICOTTS_SAMPLE_FREQ_HZ 16000
|
||||
#define PICOTTS_SAMPLE_BITS 16
|
||||
|
||||
typedef void (*picotts_output_fn)(int16_t *samples, unsigned count);
|
||||
|
||||
/**
|
||||
* Initialises the PicoTTS engine and prepares to receive TTS requests.
|
||||
* A new task is launched, which is used to run the TTS engine.
|
||||
* @param prio The priority of the TTS task.
|
||||
* @param output_cb Callback function which gets invoked directly from the
|
||||
* TTS task with a buffer of samples generated.
|
||||
* @param core The core number to bind the TTS task to, or -1 for no fixed
|
||||
* core affinity.
|
||||
* @returns True on success, false on failure.
|
||||
*/
|
||||
bool picotts_init(unsigned prio, picotts_output_fn output_cb, int core);
|
||||
|
||||
/**
|
||||
* Adds text to be synthesised. The TTS engine will wait until it sees
|
||||
* an appropriate stop (e.g. sentence stop, \0) before commencing the
|
||||
* speech generation.
|
||||
*
|
||||
* A queue is used to transfer the text to the TTS engine. The queue
|
||||
* size may be configured via Kconfig. Adding more text while the queue
|
||||
* is full will cause this function to block.
|
||||
*
|
||||
* @param txt The pointer to the text to be spoken, in UTF8 format. The
|
||||
* text is copied, so the pointer may be invalidated immediately upon
|
||||
* return from this call.
|
||||
* @param len The number of bytes available in @c text.
|
||||
*/
|
||||
void picotts_add(const char *txt, unsigned len);
|
||||
|
||||
/**
|
||||
* Stops the TTS engine task and frees the used memory resources.
|
||||
* Call @c picotts_init() again to reinitialise, if needed.
|
||||
*/
|
||||
void picotts_shutdown();
|
||||
|
||||
|
||||
typedef void (*picotts_error_notify_fn)(void);
|
||||
|
||||
/**
|
||||
* Sets a callback function to be invoked if picotts encounters and error
|
||||
* and aborts.
|
||||
* @param cb The callback handler. Invoked from the TTS task prior to said
|
||||
* task exiting. To resume TTS operation the callback should schedule a
|
||||
* reinitialisation of PicoTTS, i.e @c picotts_shutdown() followed by
|
||||
* @c picotts_init(). Pass NULL to unregister a set callback function.
|
||||
*/
|
||||
void picotts_set_error_notify(picotts_error_notify_fn cb);
|
||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
+190
@@ -0,0 +1,190 @@
|
||||
|
||||
Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License 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.
|
||||
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
+1435
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picoacph.h
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup picoacph
|
||||
*
|
||||
itemtype, iteminfo1, iteminfo2, content -> TYPE(INFO1,INFO2)content
|
||||
in the following
|
||||
|
||||
items input
|
||||
===========
|
||||
|
||||
processed by sa (POS disambiguation):
|
||||
- WORDGRAPH(POSes,NA)graph
|
||||
- WORDINDEX(POSes,NA)POS|1ind1...POSN|indN
|
||||
- CMD(PICODATA_ITEMINFO1_CMD_FLUSH,PICODATA_ITEMINFO2_NA)
|
||||
|
||||
processed by sa (Phrasing, Accentuation):
|
||||
- PUNC(PUNCtype,PUNCsubtype)
|
||||
|
||||
unprocessed:
|
||||
- all other item types are forwarded through the PU without modification:
|
||||
CMD
|
||||
|
||||
|
||||
minimal input size (before processing starts)
|
||||
==================
|
||||
|
||||
processing (POS disambiguation, g2p, lexind, phrasing, accentuation)
|
||||
is possible with
|
||||
|
||||
- one punctuation-phrase, consisting of a sequence (see below for
|
||||
limits) of items terminated by a PUNC item.
|
||||
|
||||
(possible but not implemented: as long as the internal buffer is
|
||||
empty, non-processed item types can be processed immediately)
|
||||
|
||||
Ensuring terminal PUNC item:
|
||||
- when reading items from the external buffer a CMD(...FLUSH...) is
|
||||
converted to a PUNC(...FLUSH...) item
|
||||
- If needed, a PUNC(PHRASE) is artificially added to ensure a phrase
|
||||
fits in the PUs memory and processing can start.
|
||||
|
||||
|
||||
items processed and output
|
||||
==========================
|
||||
|
||||
precondition:
|
||||
CMD(...FLUSH...) already converted to PUNC(...FLUSH...) and trailing
|
||||
PUNC item enforced if necessary.
|
||||
|
||||
----
|
||||
-# PROCESS_POSD: processing input WORDGRAPH or WORDINDEX items, after
|
||||
POS disambiguation (POSes -> POS), results in a sequence of:
|
||||
-
|
||||
- WORDGRAPH(POS,NA)graph
|
||||
- WORDINDEX(POS,NA)POS|ind
|
||||
-
|
||||
.
|
||||
-# PROCESS_WPHO: then, after lex-index lookup and G2P in a
|
||||
sequence of:
|
||||
- WORDPHON(POS,NA)phon
|
||||
|
||||
(phon containing primary and secondary word-level stress)
|
||||
|
||||
----
|
||||
3. PROCESS_PHR: then, after processing these WORDPHON items,
|
||||
together with the trailing PUNC item results in:
|
||||
|
||||
-> BOUND(BOUNDstrength,BOUNDtype)
|
||||
|
||||
being added in the sequence of WORDPHON (respectively inserted instead
|
||||
of the PUNC). All PUNC, incl PUNC(...FLUSH...) now gone.
|
||||
|
||||
----
|
||||
4. PROCESS_ACC: then, after processing the WORDPHON and BOUND items
|
||||
results in:
|
||||
|
||||
-> WORDPHON(POS,ACC)phon
|
||||
|
||||
A postprocessing step of accentuation is hard-coded in the
|
||||
accentuation module: In case the whole word does not have any stress
|
||||
at all (primary or secondary or both) then do the following mapping:
|
||||
|
||||
ACC0 nostress -> ACC0
|
||||
ACC1 nostress -> ACC3
|
||||
ACC2 nostress -> ACC3
|
||||
ACC3 nostress -> ACC3
|
||||
|
||||
----
|
||||
- POS
|
||||
a single, unambiguous POS
|
||||
|
||||
cf. picodata.h for
|
||||
- ACC (sentence-level accent (aka prominence)) %d
|
||||
- PICODATA_ACC0
|
||||
- PICODATA_ACC1
|
||||
- PICODATA_ACC2 (<- maybe mapped to ACC1, ie. no ACC2 in output)
|
||||
- PICODATA_ACC3
|
||||
|
||||
- BOUNDstrength %d
|
||||
- PICODATA_ITEMINFO1_BOUND_SBEG (at sentence start)
|
||||
- PICODATA_ITEMINFO1_BOUND_SEND (at sentence end)
|
||||
- PICODATA_ITEMINFO1_BOUND_TERM (replaces a flush)
|
||||
- PICODATA_ITEMINFO1_BOUND_PHR1 (primary boundary)
|
||||
- PICODATA_ITEMINFO1_BOUND_PHR2 (short break)
|
||||
- PICODATA_ITEMINFO1_BOUND_PHR3 (secondary phrase boundary, no break)
|
||||
- PICODATA_ITEMINFO1_BOUND_PHR0 (no break, not produced by sa, not existing
|
||||
BOUND in item sequence equals PHR0 bound strength)
|
||||
|
||||
- BOUNDtype (created in sa base on punctuation, indicates type of phrase
|
||||
following the boundary) %d
|
||||
- PICODATA_ITEMINFO2_BOUNDTYPE_P
|
||||
- PICODATA_ITEMINFO2_BOUNDTYPE_T
|
||||
- PICODATA_ITEMINFO2_BOUNDTYPE_Q
|
||||
- PICODATA_ITEMINFO2_BOUNDTYPE_E
|
||||
|
||||
|
||||
output sequence (without CMDs):
|
||||
|
||||
<output> = { BOUND(BOUND_SBEG,PHRASEtype) <sentence> BOUND(BOUND_SEND,..)} BOUND(BOUND_TERM,..)
|
||||
|
||||
<sentence> = <phrase> { BOUND(BOUND_PHR1|2|3,BOUNDtype) <phrase> }
|
||||
|
||||
<phrase> = WORDPHON(POS,ACC)phon { WORDPHON(POS,ACC)phon }
|
||||
|
||||
Done in later PU: mapping ACC & word-level stress to syllable accent value
|
||||
- ACC0 prim -> 0
|
||||
- ACC1 prim -> 1
|
||||
- ACC2 prim -> 2
|
||||
- ACC3 prim -> 3
|
||||
- ACC0 sec -> 0
|
||||
- ACC1 sec -> 4
|
||||
- ACC2 sec -> 4
|
||||
- ACC3 sec -> 4
|
||||
|
||||
other limitations
|
||||
=================
|
||||
|
||||
- item size: header plus len=256 (valid for Pico in general)
|
||||
- see defines below for max nr of items. Item heads plus ref. to contents
|
||||
buffer are stored in array with fixed size elements. Two restrictions:
|
||||
- MAXNR_HEADX (max nr elements==items in headx array)
|
||||
- CONTENTSSIZE (max size of all contents together
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PICOACPH_H_
|
||||
#define PICOACPH_H_
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picodata.h"
|
||||
#include "picorsrc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
/* nr item restriction: maximum number of extended item heads in headx */
|
||||
#define PICOACPH_MAXNR_HEADX 60
|
||||
|
||||
/* nr item restriction: maximum size of all item contents together in cont */
|
||||
#define PICOACPH_MAXSIZE_CBUF 7680
|
||||
|
||||
|
||||
|
||||
picodata_ProcessingUnit picoacph_newAccPhrUnit(
|
||||
picoos_MemoryManager mm,
|
||||
picoos_Common common,
|
||||
picodata_CharBuffer cbIn,
|
||||
picodata_CharBuffer cbOut,
|
||||
picorsrc_Voice voice);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*PICOACPH_H_*/
|
||||
@@ -0,0 +1,806 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picoapi.c
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*/
|
||||
#include "picodefs.h"
|
||||
#include "picoos.h"
|
||||
#include "picodbg.h"
|
||||
#include "picorsrc.h"
|
||||
#include "picoctrl.h"
|
||||
#include "picoapi.h"
|
||||
#include "picoapid.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ****************************************************************************/
|
||||
/* System-level API functions */
|
||||
/* ****************************************************************************/
|
||||
|
||||
#define MAGIC_MASK 0x5069636F /* Pico */
|
||||
|
||||
#define SET_MAGIC_NUMBER(sys) \
|
||||
(sys)->magic = ((picoos_uint32) (uintptr_t) (sys)) ^ MAGIC_MASK
|
||||
|
||||
#define CHECK_MAGIC_NUMBER(sys) \
|
||||
((sys)->magic == (((picoos_uint32) (uintptr_t) (sys)) ^ MAGIC_MASK))
|
||||
|
||||
|
||||
|
||||
/* *** Auxiliary routines (may also be called from picoextapi.c) **************/
|
||||
|
||||
|
||||
int is_valid_system_handle(pico_System system)
|
||||
{
|
||||
return (system != NULL) && CHECK_MAGIC_NUMBER(system);
|
||||
}
|
||||
|
||||
|
||||
picoos_Common pico_sysGetCommon(pico_System this)
|
||||
{
|
||||
if (this != NULL) {
|
||||
return this->common;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *** System initialization and termination functions ************************/
|
||||
pico_Status pico_initialize_priv(
|
||||
void *memory,
|
||||
const pico_Uint32 size,
|
||||
pico_Int16 enableMemProt,
|
||||
pico_System *system
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
PICODBG_INITIALIZE(PICODBG_LOG_LEVEL_INFO);
|
||||
PICODBG_ENABLE_COLORS(0);
|
||||
/*PICODBG_SET_OUTPUT_FORMAT((PICODBG_SHOW_LEVEL | PICODBG_SHOW_SRCNAME));*/
|
||||
|
||||
if (memory == NULL) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else if (size == 0) {
|
||||
status = PICO_ERR_INVALID_ARGUMENT;
|
||||
} else if (system == NULL) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else {
|
||||
byte_ptr_t rest_mem;
|
||||
picoos_objsize_t rest_mem_size;
|
||||
pico_System sys;
|
||||
picoos_MemoryManager sysMM;
|
||||
picoos_ExceptionManager sysEM;
|
||||
|
||||
sys = (pico_System) picoos_raw_malloc(memory, size, sizeof(pico_system_t),
|
||||
&rest_mem, &rest_mem_size);
|
||||
if (sys != NULL) {
|
||||
sysMM = picoos_newMemoryManager(rest_mem, rest_mem_size, enableMemProt ? TRUE : FALSE);
|
||||
if (sysMM != NULL) {
|
||||
sysEM = picoos_newExceptionManager(sysMM);
|
||||
sys->common = picoos_newCommon(sysMM);
|
||||
sys->rm = picorsrc_newResourceManager(sysMM, sys->common);
|
||||
if ((sysEM != NULL) && (sys->common != NULL) && (sys->rm != NULL)) {
|
||||
sys->common->em = sysEM;
|
||||
sys->common->mm = sysMM;
|
||||
sys->engine = NULL;
|
||||
|
||||
picorsrc_createDefaultResource(sys->rm /*,&defaultResource */);
|
||||
|
||||
SET_MAGIC_NUMBER(sys);
|
||||
status = PICO_OK;
|
||||
} else {
|
||||
status = PICO_EXC_OUT_OF_MEM;
|
||||
}
|
||||
} else {
|
||||
status = PICO_EXC_OUT_OF_MEM;
|
||||
}
|
||||
} else {
|
||||
status = PICO_EXC_OUT_OF_MEM;
|
||||
}
|
||||
*system = sys;
|
||||
}
|
||||
|
||||
if (status != PICO_OK) {
|
||||
if (system != NULL) {
|
||||
*system = NULL;
|
||||
}
|
||||
PICODBG_TERMINATE();
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
/**
|
||||
* pico_initialize : initializes the pico system private memory
|
||||
* @param memory : pointer to a free and already allocated memory area
|
||||
* @param size : size of the memory area
|
||||
* @param system : pointer to a pico_System struct
|
||||
* @return PICO_OK : successful init, !PICO_OK : error on allocating private memory
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_initialize(
|
||||
void *memory,
|
||||
const pico_Uint32 size,
|
||||
pico_System *system
|
||||
)
|
||||
{
|
||||
return pico_initialize_priv(memory, size, /*enableMemProt*/ FALSE, system);
|
||||
}
|
||||
|
||||
/**
|
||||
* pico_terminate : deallocates the pico system private memory
|
||||
* @param system : pointer to a pico_System struct
|
||||
* @return PICO_OK : successful de-init, !PICO_OK : error on de-allocating private memory
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_terminate(
|
||||
pico_System *system
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
if ((system == NULL) || !is_valid_system_handle(*system)) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
} else {
|
||||
pico_System sys = *system;
|
||||
|
||||
/* close engine(s) */
|
||||
picoctrl_disposeEngine(sys->common->mm, sys->rm, &sys->engine);
|
||||
|
||||
/* close all resources */
|
||||
picorsrc_disposeResourceManager(sys->common->mm, &sys->rm);
|
||||
|
||||
sys->magic ^= 0xFFFEFDFC;
|
||||
*system = NULL;
|
||||
}
|
||||
|
||||
PICODBG_TERMINATE();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *** System status and error/warning message retrieval function *************/
|
||||
|
||||
/**
|
||||
* pico_getSystemStatusMessage : Returns a description of the system status or errors
|
||||
* @param system : pointer to a pico_System struct
|
||||
* @param errCode : pico_System error code
|
||||
* @param outMessage : memory area where to return a string
|
||||
* @return PICO_OK : successful
|
||||
* @return PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_getSystemStatusMessage(
|
||||
pico_System system,
|
||||
pico_Status errCode,
|
||||
pico_Retstring outMessage
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
if (!is_valid_system_handle(system)) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
if (outMessage != NULL) {
|
||||
picoos_strlcpy((picoos_char *) outMessage, (picoos_char *) "'system' not initialized", PICO_RETSTRINGSIZE);
|
||||
}
|
||||
} else if (outMessage == NULL) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else {
|
||||
if (picoos_emGetExceptionCode(system->common->em) == PICO_OK) {
|
||||
if (errCode == PICO_OK) {
|
||||
picoos_strlcpy((picoos_char *) outMessage, (picoos_char *) "system ok", PICO_RETSTRINGSIZE);
|
||||
} else {
|
||||
/* exceptionManager was not informed yet; produce default message */
|
||||
picoos_setErrorMsg((picoos_char *) outMessage, PICO_RETSTRINGSIZE, errCode, NULL, NULL, NULL);
|
||||
}
|
||||
} else {
|
||||
picoos_emGetExceptionMessage(system->common->em, (picoos_char *) outMessage, PICO_RETSTRINGSIZE);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* pico_getSystemStatusMessage : Returns the number of warnings
|
||||
* @param system : pointer to a pico_System struct
|
||||
* @param *outNrOfWarnings : pointer to location to receive number of warnings
|
||||
* @return PICO_OK : successful
|
||||
* @return PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_getNrSystemWarnings(
|
||||
pico_System system,
|
||||
pico_Int32 *outNrOfWarnings
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
if (!is_valid_system_handle(system)) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
if (outNrOfWarnings != NULL) {
|
||||
*outNrOfWarnings = 0;
|
||||
}
|
||||
} else if (outNrOfWarnings == NULL) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else {
|
||||
*outNrOfWarnings = picoos_emGetNumOfWarnings(system->common->em);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* pico_getSystemWarning : Returns a description of a warning
|
||||
* @param system : pointer to a pico_System struct
|
||||
* @param warningIndex : warning index
|
||||
* @param *outCode : pointer to receive the warning code
|
||||
* @param outMessage : pointer to receive the output message
|
||||
* @return PICO_OK : successful
|
||||
* @return PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_getSystemWarning(
|
||||
pico_System system,
|
||||
const pico_Int32 warningIndex,
|
||||
pico_Status *outCode,
|
||||
pico_Retstring outMessage
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
if (!is_valid_system_handle(system)) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
if (outMessage != NULL) {
|
||||
picoos_strlcpy((picoos_char *) outMessage, (picoos_char *) "'system' not initialized", PICO_RETSTRINGSIZE);
|
||||
}
|
||||
} else if (warningIndex < 0) {
|
||||
status = PICO_ERR_INDEX_OUT_OF_RANGE;
|
||||
} else if ((outCode == NULL) || (outMessage == NULL)) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else {
|
||||
*outCode = picoos_emGetWarningCode(system->common->em, warningIndex);
|
||||
picoos_emGetWarningMessage(system->common->em, warningIndex, (picoos_char *) outMessage, (picoos_uint16) PICO_RETSTRINGSIZE);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *** Resource loading and unloading functions *******************************/
|
||||
|
||||
/**
|
||||
* pico_loadResource : Loads a resource file into the Pico system
|
||||
* @param system : pointer to a pico_System struct
|
||||
* @param *lingwareFileName : lingware resource file name
|
||||
* @param *outLingware : pointer to receive the loaded lingware resource memory area address
|
||||
* @return PICO_OK : successful
|
||||
* @return PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_loadResource(
|
||||
pico_System system,
|
||||
const pico_Char *lingwareFileName,
|
||||
pico_Resource *outLingware
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
if (!is_valid_system_handle(system)) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
} else if ((lingwareFileName == NULL) || (outLingware == NULL)) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else {
|
||||
PICODBG_DEBUG(("memory usage before resource loading"));
|
||||
picoos_showMemUsage(system->common->mm, FALSE, TRUE);
|
||||
picoos_emReset(system->common->em);
|
||||
status = picorsrc_loadResource(system->rm, (picoos_char *) lingwareFileName, (picorsrc_Resource *) outLingware);
|
||||
PICODBG_DEBUG(("memory used to load resource %s", lingwareFileName));
|
||||
picoos_showMemUsage(system->common->mm, TRUE, FALSE);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* pico_unloadResource : unLoads a resource file from the Pico system
|
||||
* @param system : pointer to a pico_System struct
|
||||
* @param *inoutLingware : pointer to the loaded lingware resource memory area address
|
||||
* @return PICO_OK : successful
|
||||
* @return PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_unloadResource(
|
||||
pico_System system,
|
||||
pico_Resource *inoutLingware
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
if (!is_valid_system_handle(system)) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
} else if (inoutLingware == NULL) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else if (!picoctrl_isValidResourceHandle(*((picorsrc_Resource *) inoutLingware))) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
} else {
|
||||
PICODBG_DEBUG(("memory usage before resource unloading"));
|
||||
picoos_showMemUsage(system->common->mm, FALSE, TRUE);
|
||||
picoos_emReset(system->common->em);
|
||||
status = picorsrc_unloadResource(system->rm, (picorsrc_Resource *) inoutLingware);
|
||||
PICODBG_DEBUG(("memory released by resource unloading"));
|
||||
picoos_showMemUsage(system->common->mm, TRUE, FALSE);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* *** Resource inspection functions *******************************/
|
||||
/**
|
||||
* pico_getResourceName : Gets a resource name
|
||||
* @param system : pointer to a pico_System struct
|
||||
* @param resource : pointer to the loaded resource memory area address
|
||||
* @param outName : pointer to the area to receuive the resource name
|
||||
* @return PICO_OK : successful
|
||||
* @return PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_getResourceName(
|
||||
pico_System system,
|
||||
pico_Resource resource,
|
||||
pico_Retstring outName) {
|
||||
|
||||
if (!is_valid_system_handle(system)) {
|
||||
return PICO_ERR_INVALID_HANDLE;
|
||||
} else if (NULL == outName) {
|
||||
return PICO_ERR_NULLPTR_ACCESS;
|
||||
}
|
||||
return picorsrc_rsrcGetName((picorsrc_Resource)resource, (picoos_char *) outName, PICO_RETSTRINGSIZE);
|
||||
}
|
||||
|
||||
|
||||
/* *** Voice definition functions *********************************************/
|
||||
|
||||
/**
|
||||
* pico_createVoiceDefinition : Creates a voice definition
|
||||
* @param system : pointer to a pico_System struct
|
||||
* @param *voiceName : pointer to the area to receive the voice definition
|
||||
* @return PICO_OK : successful
|
||||
* @return PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_createVoiceDefinition(
|
||||
pico_System system,
|
||||
const pico_Char *voiceName
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
if (!is_valid_system_handle(system)) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
} else if (voiceName == NULL) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else if (picoos_strlen((picoos_char *) voiceName) == 0) {
|
||||
status = PICO_ERR_INVALID_ARGUMENT;
|
||||
} else {
|
||||
picoos_emReset(system->common->em);
|
||||
status = picorsrc_createVoiceDefinition(system->rm, (picoos_char *) voiceName);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* pico_addResourceToVoiceDefinition : Adds a mapping pair to a voice definition
|
||||
* @param system : pointer to a pico_System struct
|
||||
* @param *voiceName : pointer to the area containing the voice definition
|
||||
* @param *resourceName : pointer to the area containing the resource name
|
||||
* @return PICO_OK : successful
|
||||
* @return PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_addResourceToVoiceDefinition(
|
||||
pico_System system,
|
||||
const pico_Char *voiceName,
|
||||
const pico_Char *resourceName
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
if (!is_valid_system_handle(system)) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
} else if (voiceName == NULL) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else if (picoos_strlen((picoos_char *) voiceName) == 0) {
|
||||
status = PICO_ERR_INVALID_ARGUMENT;
|
||||
} else if (resourceName == NULL) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else if (picoos_strlen((picoos_char *) resourceName) == 0) {
|
||||
status = PICO_ERR_INVALID_ARGUMENT;
|
||||
} else {
|
||||
picoos_emReset(system->common->em);
|
||||
status = picorsrc_addResourceToVoiceDefinition(system->rm, (picoos_char *) voiceName, (picoos_char *) resourceName);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* pico_releaseVoiceDefinition : Releases a voice definition
|
||||
* @param system : pointer to a pico_System struct
|
||||
* @param *voiceName : pointer to the area containing the voice definition
|
||||
* @return PICO_OK : successful
|
||||
* @return PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_releaseVoiceDefinition(
|
||||
pico_System system,
|
||||
const pico_Char *voiceName
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
if (!is_valid_system_handle(system)) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
} else if (voiceName == NULL) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else if (picoos_strlen((picoos_char *) voiceName) == 0) {
|
||||
status = PICO_ERR_INVALID_ARGUMENT;
|
||||
} else {
|
||||
picoos_emReset(system->common->em);
|
||||
status = picorsrc_releaseVoiceDefinition(system->rm, (picoos_char *) voiceName);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *** Engine creation and deletion functions *********************************/
|
||||
|
||||
/**
|
||||
* pico_newEngine : Creates and initializes a new Pico engine
|
||||
* @param system : pointer to a pico_System struct
|
||||
* @param *voiceName : pointer to the area containing the voice definition
|
||||
* @param *outEngine : pointer to the Pico engine handle
|
||||
* @return PICO_OK : successful
|
||||
* @return PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_newEngine(
|
||||
pico_System system,
|
||||
const pico_Char *voiceName,
|
||||
pico_Engine *outEngine
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
PICODBG_DEBUG(("creating engine for voice '%s'", (picoos_char *) voiceName));
|
||||
|
||||
if (!is_valid_system_handle(system)) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
} else if (voiceName == NULL) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else if (picoos_strlen((picoos_char *) voiceName) == 0) {
|
||||
status = PICO_ERR_INVALID_ARGUMENT;
|
||||
} else if (outEngine == NULL) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else {
|
||||
picoos_emReset(system->common->em);
|
||||
if (system->engine == NULL) {
|
||||
*outEngine = (pico_Engine) picoctrl_newEngine(system->common->mm, system->rm, voiceName);
|
||||
if (*outEngine != NULL) {
|
||||
system->engine = (picoctrl_Engine) *outEngine;
|
||||
} else {
|
||||
status = picoos_emRaiseException(system->common->em, PICO_EXC_OUT_OF_MEM,
|
||||
(picoos_char *) "out of memory creating new engine", NULL);
|
||||
}
|
||||
} else {
|
||||
status = picoos_emRaiseException(system->common->em, PICO_EXC_MAX_NUM_EXCEED,
|
||||
NULL, (picoos_char *) "no more than %i engines", 1);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* pico_disposeEngine : Disposes a Pico engine
|
||||
* @param system : pointer to a pico_System struct
|
||||
* @param *inoutEngine : pointer to the Pico engine handle
|
||||
* @return PICO_OK : successful
|
||||
* @return PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_disposeEngine(
|
||||
pico_System system,
|
||||
pico_Engine *inoutEngine
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
if (!is_valid_system_handle(system)) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
} else if (inoutEngine == NULL) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else if (!picoctrl_isValidEngineHandle(*((picoctrl_Engine *) inoutEngine))) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
} else {
|
||||
picoos_emReset(system->common->em);
|
||||
picoctrl_disposeEngine(system->common->mm, system->rm, (picoctrl_Engine *) inoutEngine);
|
||||
system->engine = NULL;
|
||||
status = picoos_emGetExceptionCode(system->common->em);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ****************************************************************************/
|
||||
/* Engine-level API functions */
|
||||
/* ****************************************************************************/
|
||||
|
||||
/**
|
||||
* pico_putTextUtf8 : Puts UTF8 text into Pico text input buffer
|
||||
* @param engine : pointer to a Pico engine handle
|
||||
* @param *text : pointer to the text buffer
|
||||
* @param textSize : text buffer size
|
||||
* @param *bytesPut : pointer to variable to receive the number of bytes put
|
||||
* @return PICO_OK : successful
|
||||
* @return PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_putTextUtf8(
|
||||
pico_Engine engine,
|
||||
const pico_Char *text,
|
||||
const pico_Int16 textSize,
|
||||
pico_Int16 *bytesPut)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
} else if (text == NULL) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else if (textSize < 0) {
|
||||
status = PICO_ERR_INVALID_ARGUMENT;
|
||||
} else if (bytesPut == NULL) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else {
|
||||
picoctrl_engResetExceptionManager((picoctrl_Engine) engine);
|
||||
status = picoctrl_engFeedText((picoctrl_Engine) engine, (picoos_char *)text, textSize, bytesPut);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* pico_getData : Gets speech data from the engine.
|
||||
* @param engine : pointer to a Pico engine handle
|
||||
* @param *buffer : pointer to output buffer
|
||||
* @param bufferSize : out buffer size
|
||||
* @param *bytesReceived : pointer to a variable to receive the number of bytes received
|
||||
* @param *outDataType : pointer to a variable to receive the type of buffer received
|
||||
* @return PICO_OK : successful
|
||||
* @return PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_getData(
|
||||
pico_Engine engine,
|
||||
void *buffer,
|
||||
const pico_Int16 bufferSize,
|
||||
pico_Int16 *bytesReceived,
|
||||
pico_Int16 *outDataType
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
|
||||
status = PICO_STEP_ERROR;
|
||||
} else if (buffer == NULL) {
|
||||
status = PICO_STEP_ERROR;
|
||||
} else if (bufferSize < 0) {
|
||||
status = PICO_STEP_ERROR;
|
||||
} else if (bytesReceived == NULL) {
|
||||
status = PICO_STEP_ERROR;
|
||||
} else {
|
||||
picoctrl_engResetExceptionManager((picoctrl_Engine) engine);
|
||||
status = picoctrl_engFetchOutputItemBytes((picoctrl_Engine) engine, (picoos_char *)buffer, bufferSize, bytesReceived);
|
||||
if ((status != PICO_STEP_IDLE) && (status != PICO_STEP_BUSY)) {
|
||||
status = PICO_STEP_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
*outDataType = PICO_DATA_PCM_16BIT;
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* pico_resetEngine : Resets the engine
|
||||
* @param engine : pointer to a Pico engine handle
|
||||
* @param resetMode : reset mode; one of PICO_RESET_FULL or PICO_RESET_SOFT
|
||||
* @return PICO_OK : successful
|
||||
* @return PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_resetEngine(
|
||||
pico_Engine engine,
|
||||
pico_Int32 resetMode)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
} else {
|
||||
picoctrl_engResetExceptionManager((picoctrl_Engine) engine);
|
||||
|
||||
resetMode = (PICO_RESET_SOFT == resetMode) ? PICO_RESET_SOFT : PICO_RESET_FULL;
|
||||
|
||||
status = picoctrl_engReset((picoctrl_Engine) engine, (picoos_int32)resetMode);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* pico_getEngineStatusMessage : Returns the engine status or error description
|
||||
* @param engine : pointer to a Pico engine handle
|
||||
* @param errCode : error code
|
||||
* @param outMessage : pointer to a memory area to receive the output message
|
||||
* @return PICO_OK : successful
|
||||
* @return PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_getEngineStatusMessage(
|
||||
pico_Engine engine,
|
||||
pico_Status errCode,
|
||||
pico_Retstring outMessage
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
PICODBG_DEBUG(("got error code %i", errCode));
|
||||
|
||||
if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
if (outMessage != NULL) {
|
||||
picoos_strlcpy((picoos_char *) outMessage, (picoos_char *) "'engine' not initialized", PICO_RETSTRINGSIZE);
|
||||
}
|
||||
} else if (outMessage == NULL) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else {
|
||||
picoos_Common common = picoctrl_engGetCommon((picoctrl_Engine) engine);
|
||||
if (picoos_emGetExceptionCode(common->em) == PICO_OK) {
|
||||
if (errCode == PICO_OK) {
|
||||
picoos_strlcpy((picoos_char *) outMessage, (picoos_char *) "engine ok", PICO_RETSTRINGSIZE);
|
||||
} else {
|
||||
/* exceptionManager was not informed yet; produce default message */
|
||||
picoos_setErrorMsg((picoos_char *) outMessage, PICO_RETSTRINGSIZE, errCode, NULL, NULL, NULL);
|
||||
}
|
||||
} else {
|
||||
picoos_emGetExceptionMessage(common->em, (picoos_char *) outMessage, PICO_RETSTRINGSIZE);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* pico_getNrEngineWarnings : Returns the number of warnings
|
||||
* @param engine : pointer to a Pico engine handle
|
||||
* @param *outNrOfWarnings: pointer to a variable to receive the number of warnings
|
||||
* @return PICO_OK : successful
|
||||
* @return PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_getNrEngineWarnings(
|
||||
pico_Engine engine,
|
||||
pico_Int32 *outNrOfWarnings
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
if (outNrOfWarnings != NULL) {
|
||||
*outNrOfWarnings = 0;
|
||||
}
|
||||
} else if (outNrOfWarnings == NULL) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else {
|
||||
picoos_Common common = picoctrl_engGetCommon((picoctrl_Engine) engine);
|
||||
*outNrOfWarnings = picoos_emGetNumOfWarnings(common->em);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* pico_getEngineWarning : Returns a description of a warning
|
||||
* @param engine : pointer to a Pico engine handle
|
||||
* @param warningIndex : warning index
|
||||
* @param *outCode: pointer to a variable to receive the warning code
|
||||
* @param outMessage: pointer to a memory area to receive the warning description
|
||||
* @return PICO_OK : successful
|
||||
* @return PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
PICO_FUNC pico_getEngineWarning(
|
||||
pico_Engine engine,
|
||||
const pico_Int32 warningIndex,
|
||||
pico_Status *outCode,
|
||||
pico_Retstring outMessage
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
if (outMessage != NULL) {
|
||||
picoos_strlcpy((picoos_char *) outMessage, (picoos_char *) "'engine' not initialized", PICO_RETSTRINGSIZE);
|
||||
}
|
||||
} else if (warningIndex < 0) {
|
||||
status = PICO_ERR_INDEX_OUT_OF_RANGE;
|
||||
} else if ((outCode == NULL) || (outMessage == NULL)) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else {
|
||||
picoos_Common common = picoctrl_engGetCommon((picoctrl_Engine) engine);
|
||||
*outCode = picoos_emGetWarningCode(common->em, warningIndex);
|
||||
picoos_emGetWarningMessage(common->em, warningIndex, (picoos_char *) outMessage, (picoos_uint16) PICO_RETSTRINGSIZE);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* end */
|
||||
@@ -0,0 +1,472 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picoapi.h
|
||||
*
|
||||
* SVOX Pico application programming interface
|
||||
* (SVOX Pico version 1.0 and later)
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup picoapi
|
||||
*
|
||||
@b Basic_Concepts
|
||||
|
||||
@e SVOX_Pico_System
|
||||
|
||||
The SVOX Pico 'system' is the entity that manages data common to all
|
||||
SVOX Pico engines, e.g. linguistic data needed to do text-to-speech
|
||||
(TTS) synthesis, license key, etc. All API functions on the Pico
|
||||
system level take a 'pico_System' handle as the first parameter.
|
||||
|
||||
@e SVOX_Pico_Engine
|
||||
|
||||
A SVOX Pico 'engine' provides the functions needed to perform actual
|
||||
synthesis. Currently there can be only one engine instance at a time
|
||||
(concurrent engines will be possible in the future). All API functions
|
||||
at the engine level take a 'pico_Engine' handle as the first
|
||||
parameter.
|
||||
|
||||
@e SVOX_Pico_Resource
|
||||
|
||||
A SVOX Pico 'resource' denotes all the language- and speaker-dependent
|
||||
data needed to do TTS synthesis. In the following, the term 'resource'
|
||||
may be used interchangeably with the term 'lingware'. A resource file
|
||||
contains a set of knowledge bases for an entire TTS voice or parts of
|
||||
it.
|
||||
|
||||
|
||||
@b Basic_Usage
|
||||
|
||||
In its most basic form, an application must call the following
|
||||
functions in order to perform TTS synthesis:
|
||||
|
||||
- pico_initialize
|
||||
- pico_loadResource
|
||||
- pico_createVoiceDefinition
|
||||
- pico_addResourceToVoiceDefinition
|
||||
- pico_newEngine
|
||||
- pico_putTextUtf8
|
||||
- pico_getData (several times)
|
||||
- pico_disposeEngine
|
||||
- pico_releaseVoiceDefinition
|
||||
- pico_unloadResource
|
||||
- pico_terminate
|
||||
|
||||
It is possible to repeatedly run the above sequence, i.e., the SVOX
|
||||
Pico system may be initialized and terminated multiple times. This may
|
||||
be useful in applications that need TTS functionality only from time
|
||||
to time.
|
||||
|
||||
|
||||
@b Conventions
|
||||
|
||||
@e Function_arguments
|
||||
|
||||
All arguments that only return values are marked by a leading 'out...'
|
||||
in their name. All arguments that are used as input and output values
|
||||
are marked by a leading 'inout...'. All other arguments are read-only
|
||||
(input) arguments.
|
||||
|
||||
@e Error_handling
|
||||
|
||||
All API functions return a status code which is one of the status
|
||||
constants defined in picodefs.h. In case of an error, a more detailed
|
||||
description of the status can be retrieved by calling function
|
||||
'pico_getSystemStatusMessage' (or 'pico_getEngineStatusMessage'
|
||||
if the error happened on the SVOX Pico engine level).
|
||||
|
||||
Unlike errors, warnings do not prevent an API function from performing
|
||||
its function, but output might not be as intended. Functions
|
||||
'pico_getNrSystemWarnings' and 'pico_getNrEngineWarnings' respectively
|
||||
can be used to determine whether an API function caused any
|
||||
warnings. Details about warnings can be retrieved by calling
|
||||
'pico_getSystemWarning' and 'pico_getEngineWarning' respectively.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef PICOAPI_H_
|
||||
#define PICOAPI_H_
|
||||
|
||||
|
||||
|
||||
#include "picodefs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
# define PICO_EXPORT __declspec( dllexport )
|
||||
#else
|
||||
# define PICO_EXPORT extern
|
||||
#endif
|
||||
|
||||
#define PICO_FUNC PICO_EXPORT pico_Status
|
||||
|
||||
|
||||
|
||||
/* ********************************************************************/
|
||||
/* PICO data types */
|
||||
/* ********************************************************************/
|
||||
|
||||
/* Handle types (opaque) for Pico system, resource, engine ************/
|
||||
|
||||
typedef struct pico_system *pico_System;
|
||||
typedef struct pico_resource *pico_Resource;
|
||||
typedef struct pico_engine *pico_Engine;
|
||||
|
||||
|
||||
/* Signed/unsigned integer data types *********************************/
|
||||
|
||||
#define PICO_INT16_MAX 32767
|
||||
#define PICO_UINT16_MAX 0xffff
|
||||
#define PICO_INT32_MAX 2147483647
|
||||
#define PICO_UINT32_MAX 0xffffffff
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#if (SHRT_MAX == PICO_INT16_MAX)
|
||||
typedef short pico_Int16;
|
||||
#else
|
||||
#error "platform not supported"
|
||||
#endif
|
||||
|
||||
#if (USHRT_MAX == PICO_UINT16_MAX)
|
||||
typedef unsigned short pico_Uint16;
|
||||
#else
|
||||
#error "platform not supported"
|
||||
#endif
|
||||
|
||||
#if (INT_MAX == PICO_INT32_MAX)
|
||||
typedef int pico_Int32;
|
||||
#else
|
||||
#error "platform not supported"
|
||||
#endif
|
||||
|
||||
#if (UINT_MAX == PICO_UINT32_MAX)
|
||||
typedef unsigned int pico_Uint32;
|
||||
#else
|
||||
#error "platform not supported"
|
||||
#endif
|
||||
|
||||
|
||||
/* Char data type *****************************************************/
|
||||
|
||||
typedef unsigned char pico_Char;
|
||||
|
||||
|
||||
/* String type to be used when ASCII string values are returned *******/
|
||||
|
||||
#define PICO_RETSTRINGSIZE 200 /* maximum length of returned strings */
|
||||
|
||||
typedef char pico_Retstring[PICO_RETSTRINGSIZE];
|
||||
|
||||
|
||||
|
||||
/* ********************************************************************/
|
||||
/* System-level API functions */
|
||||
/* ********************************************************************/
|
||||
|
||||
/* System initialization and termination functions ********************/
|
||||
|
||||
/**
|
||||
Initializes the Pico system and returns its handle in 'outSystem'.
|
||||
'memory' and 'size' define the location and maximum size of memory
|
||||
in number of bytes that the Pico system will use. The minimum size
|
||||
required depends on the number of engines and configurations of
|
||||
lingware to be used. No additional memory will be allocated by the
|
||||
Pico system. This function must be called before any other API
|
||||
function is called. It may only be called once (e.g. at application
|
||||
startup), unless a call to 'pico_terminate'.
|
||||
*/
|
||||
PICO_FUNC pico_initialize(
|
||||
void *memory,
|
||||
const pico_Uint32 size,
|
||||
pico_System *outSystem
|
||||
);
|
||||
|
||||
/**
|
||||
Terminates the Pico system. Lingware resources still being loaded
|
||||
are unloaded automatically. The memory area provided to Pico in
|
||||
'pico_initialize' is released. The system handle becomes
|
||||
invalid. It is not allowed to call this function as long as Pico
|
||||
engine instances are existing. No API function may be called after
|
||||
this function, except for 'pico_initialize', which reinitializes
|
||||
the system.
|
||||
*/
|
||||
PICO_FUNC pico_terminate(
|
||||
pico_System *system
|
||||
);
|
||||
|
||||
|
||||
/* System status and error/warning message retrieval ******************/
|
||||
|
||||
/**
|
||||
Returns in 'outMessage' a description of the system status or of an
|
||||
error that occurred with the most recently called system-level API
|
||||
function.
|
||||
*/
|
||||
PICO_FUNC pico_getSystemStatusMessage(
|
||||
pico_System system,
|
||||
pico_Status errCode,
|
||||
pico_Retstring outMessage
|
||||
);
|
||||
|
||||
/**
|
||||
Returns in 'outNrOfWarnings' the number of warnings that occurred
|
||||
with the most recently called system-level API function.
|
||||
*/
|
||||
PICO_FUNC pico_getNrSystemWarnings(
|
||||
pico_System system,
|
||||
pico_Int32 *outNrOfWarnings
|
||||
);
|
||||
|
||||
/**
|
||||
Returns in 'outMessage' a description of a warning that occurred
|
||||
with the most recently called system-level API function.
|
||||
'warningIndex' must be in the range 0..N-1 where N is the number of
|
||||
warnings returned by 'pico_getNrSystemWarnings'. 'outCode' returns
|
||||
the warning as an integer code (cf. PICO_WARN_*).
|
||||
*/
|
||||
PICO_FUNC pico_getSystemWarning(
|
||||
pico_System system,
|
||||
const pico_Int32 warningIndex,
|
||||
pico_Status *outCode,
|
||||
pico_Retstring outMessage
|
||||
);
|
||||
|
||||
|
||||
/* Resource loading and unloading functions ***************************/
|
||||
|
||||
/**
|
||||
Loads a resource file into the Pico system. The number of resource
|
||||
files loaded in parallel is limited by PICO_MAX_NUM_RESOURCES.
|
||||
Loading of a resource file may be done at any time (even in
|
||||
parallel to a running engine doing TTS synthesis), but with the
|
||||
general restriction that functions taking a system handle as their
|
||||
first argument must be called in a mutually exclusive fashion. The
|
||||
loaded resource will be available only to engines started after the
|
||||
resource is fully loaded, i.e., not to engines currently
|
||||
running.
|
||||
*/
|
||||
PICO_FUNC pico_loadResource(
|
||||
pico_System system,
|
||||
const pico_Char *resourceFileName,
|
||||
pico_Resource *outResource
|
||||
);
|
||||
|
||||
/**
|
||||
Unloads a resource file from the Pico system. If no engine uses the
|
||||
resource file, the resource is removed immediately and its
|
||||
associated internal memory is released, otherwise
|
||||
PICO_EXC_RESOURCE_BUSY is returned.
|
||||
*/
|
||||
PICO_FUNC pico_unloadResource(
|
||||
pico_System system,
|
||||
pico_Resource *inoutResource
|
||||
);
|
||||
|
||||
/* *** Resource inspection functions *******************************/
|
||||
|
||||
/**
|
||||
Gets the unique resource name of a loaded resource
|
||||
*/
|
||||
PICO_FUNC pico_getResourceName(
|
||||
pico_System system,
|
||||
pico_Resource resource,
|
||||
pico_Retstring outName);
|
||||
|
||||
|
||||
/* Voice definition ***************************************************/
|
||||
|
||||
/**
|
||||
Creates a voice definition. Resources must be added to the created
|
||||
voice with 'pico_addResourceToVoiceDefinition' before using the
|
||||
voice in 'pico_newEngine'. It is an error to create a voice
|
||||
definition with a previously defined voice name. In that case use
|
||||
'pico_releaseVoiceName' first.
|
||||
*/
|
||||
PICO_FUNC pico_createVoiceDefinition(
|
||||
pico_System system,
|
||||
const pico_Char *voiceName
|
||||
);
|
||||
|
||||
/**
|
||||
Adds a mapping pair ('voiceName', 'resourceName') to the voice
|
||||
definition. Multiple mapping pairs can added to a voice defintion.
|
||||
When calling 'pico_newEngine' with 'voiceName', the corresponding
|
||||
resources from the mappings will be used with that engine. */
|
||||
|
||||
PICO_FUNC pico_addResourceToVoiceDefinition(
|
||||
pico_System system,
|
||||
const pico_Char *voiceName,
|
||||
const pico_Char *resourceName
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Releases the voice definition 'voiceName'.
|
||||
|
||||
*/
|
||||
PICO_FUNC pico_releaseVoiceDefinition(
|
||||
pico_System system,
|
||||
const pico_Char *voiceName
|
||||
);
|
||||
|
||||
|
||||
/* Engine creation and deletion functions *****************************/
|
||||
|
||||
/**
|
||||
Creates and initializes a new Pico engine instance and returns its
|
||||
handle in 'outEngine'. Only one instance per system is currently
|
||||
possible.
|
||||
*/
|
||||
PICO_FUNC pico_newEngine(
|
||||
pico_System system,
|
||||
const pico_Char *voiceName,
|
||||
pico_Engine *outEngine
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Disposes a Pico engine and releases all memory it occupied. The
|
||||
engine handle becomes invalid.
|
||||
*/
|
||||
PICO_FUNC pico_disposeEngine(
|
||||
pico_System system,
|
||||
pico_Engine *inoutEngine
|
||||
);
|
||||
|
||||
|
||||
|
||||
/* ********************************************************************/
|
||||
/* Engine-level API functions */
|
||||
/* ********************************************************************/
|
||||
|
||||
/**
|
||||
Puts text 'text' encoded in UTF8 into the Pico text input buffer.
|
||||
'textSize' is the maximum size in number of bytes accessible in
|
||||
'text'. The input text may also contain text-input commands to
|
||||
change, for example, speed or pitch of the resulting speech
|
||||
output. The number of bytes actually copied to the Pico text input
|
||||
buffer is returned in 'outBytesPut'. Sentence ends are
|
||||
automatically detected. '\0' characters may be embedded in 'text'
|
||||
to finish text input or separate independently to be synthesized
|
||||
text parts from each other. Repeatedly calling 'pico_getData' will
|
||||
result in the content of the text input buffer to be synthesized
|
||||
(up to the last sentence end or '\0' character detected). To empty
|
||||
the internal buffers without finishing synthesis, use the function
|
||||
'pico_resetEngine'.
|
||||
*/
|
||||
PICO_FUNC pico_putTextUtf8(
|
||||
pico_Engine engine,
|
||||
const pico_Char *text,
|
||||
const pico_Int16 textSize,
|
||||
pico_Int16 *outBytesPut
|
||||
);
|
||||
|
||||
/**
|
||||
Gets speech data from the engine. Every time this function is
|
||||
called, the engine performs, within a short time slot, a small
|
||||
amount of processing its input text, and then gives control back to
|
||||
the calling application. Ie. after calling 'pico_putTextUtf8'
|
||||
(incl. a final embedded '\0'), this function needs to be called
|
||||
repeatedly till 'outBytesReceived' bytes are returned in
|
||||
'outBuffer'. The type of data returned in 'outBuffer' (e.g. 8 or 16
|
||||
bit PCM samples) is returned in 'outDataType' and depends on the
|
||||
lingware resources. Possible 'outDataType' values are listed in
|
||||
picodefs.h (PICO_DATA_*).
|
||||
This function returns PICO_STEP_BUSY while processing input and
|
||||
producing speech output. Once all data is returned and there is no
|
||||
more input text available in the Pico text input buffer,
|
||||
PICO_STEP_IDLE is returned. All other function return values
|
||||
indicate a system error.
|
||||
*/
|
||||
PICO_FUNC pico_getData(
|
||||
pico_Engine engine,
|
||||
void *outBuffer,
|
||||
const pico_Int16 bufferSize,
|
||||
pico_Int16 *outBytesReceived,
|
||||
pico_Int16 *outDataType
|
||||
);
|
||||
|
||||
/**
|
||||
Resets the engine and clears all engine-internal buffers, in
|
||||
particular text input and signal data output buffers.
|
||||
'resetMode' is one of 'PICO_RESET_SOFT', to be used to flush the engine,
|
||||
or 'PICO_RESET_FULL', to reset the engine after an engine error.
|
||||
*/
|
||||
PICO_FUNC pico_resetEngine(
|
||||
pico_Engine engine,
|
||||
pico_Int32 resetMode
|
||||
);
|
||||
|
||||
|
||||
/* Engine status and error/warning message retrieval ******************/
|
||||
|
||||
/**
|
||||
Returns in 'outMessage' a description of the engine status or of an
|
||||
error that occurred with the most recently called engine-level API
|
||||
function.
|
||||
*/
|
||||
PICO_FUNC pico_getEngineStatusMessage(
|
||||
pico_Engine engine,
|
||||
pico_Status errCode,
|
||||
pico_Retstring outMessage
|
||||
);
|
||||
|
||||
/**
|
||||
Returns in 'outNrOfWarnings' the number of warnings that occurred
|
||||
with the most recently called engine-level API function.
|
||||
*/
|
||||
PICO_FUNC pico_getNrEngineWarnings(
|
||||
pico_Engine engine,
|
||||
pico_Int32 *outNrOfWarnings
|
||||
);
|
||||
|
||||
/**
|
||||
Returns in 'outMessage' a description of a warning that occurred
|
||||
with the most recently called engine-level API function.
|
||||
'warningIndex' must be in the range 0..N-1 where N is the number of
|
||||
warnings returned by 'pico_getNrEngineWarnings'. 'outCode' returns
|
||||
the warning as an integer code (cf. PICO_WARN_*).
|
||||
*/
|
||||
PICO_FUNC pico_getEngineWarning(
|
||||
pico_Engine engine,
|
||||
const pico_Int32 warningIndex,
|
||||
pico_Status *outCode,
|
||||
pico_Retstring outMessage
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*PICOAPI_H_*/
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picoapid.h
|
||||
*
|
||||
* Pico api definitions commonly used by picoapi and picoapiext
|
||||
*
|
||||
* This header file must be part of the runtime-only pico system and therefore
|
||||
* must not include picoapiext.h!
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PICOAPID_H_
|
||||
#define PICOAPID_H_
|
||||
|
||||
#include "picodefs.h"
|
||||
#include "picoapi.h"
|
||||
#include "picoos.h"
|
||||
#include "picorsrc.h"
|
||||
#include "picoctrl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Pico system descriptor */
|
||||
typedef struct pico_system {
|
||||
picoos_uint32 magic; /* magic number used to validate handles */
|
||||
picoos_Common common;
|
||||
picorsrc_ResourceManager rm;
|
||||
picoctrl_Engine engine;
|
||||
} pico_system_t;
|
||||
|
||||
|
||||
/* declared in picoapi.c */
|
||||
extern int is_valid_system_handle(pico_System system);
|
||||
extern picoos_Common pico_sysGetCommon(pico_System this);
|
||||
|
||||
|
||||
#if 0
|
||||
{
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PICOAPID_H_ */
|
||||
+1243
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picobase.h
|
||||
*
|
||||
* base functionality
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PICOBASE_H_
|
||||
#define PICOBASE_H_
|
||||
|
||||
#include "picoos.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
/* maximum number of bytes of an UTF8 character */
|
||||
#define PICOBASE_UTF8_MAXLEN 4
|
||||
|
||||
typedef picoos_uint8 picobase_utf8char[PICOBASE_UTF8_MAXLEN+1]; /* always zero terminated */
|
||||
typedef picoos_uint8 picobase_utf8;
|
||||
typedef picoos_uint16 picobase_utf16;
|
||||
typedef picoos_uint32 picobase_utf32;
|
||||
|
||||
/* ***************************************************************/
|
||||
/* Unicode UTF8 functions */
|
||||
/* ***************************************************************/
|
||||
|
||||
/**
|
||||
* Determines the number of UTF8 characters contained in
|
||||
* the UTF8 string 'utf8str' of maximum length maxlen (in bytes)
|
||||
* @param utf8str : a string encoded in UTF8
|
||||
* @param maxlen : max length (in bytes) accessible in utf8str
|
||||
* @return >=0 : length of the UTF8 string in number of UTF8 characters
|
||||
* up to the first '\0' or maxlen
|
||||
* @return <0 : not starting with a valid UTF8 character
|
||||
* @remarks strict implementation, not allowing invalid utf8
|
||||
*/
|
||||
picoos_int32 picobase_utf8_length(const picoos_uint8 *utf8str,
|
||||
const picoos_uint16 maxlen);
|
||||
|
||||
|
||||
/**
|
||||
* Determines the number of bytes an UTF8 character used based
|
||||
* on the first byte of the UTF8 character
|
||||
* @param firstchar: the first (and maybe only) byte of an UTF8 character
|
||||
* @return positive value in {1,4} : number of bytes of the UTF8 character
|
||||
* @return 0 :if not a valid UTF8 character start
|
||||
* @remarks strict implementation, not allowing invalid utf8
|
||||
*/
|
||||
/* picoos_uint8 picobase_det_utf8_length(const picoos_uint8 firstchar); */
|
||||
|
||||
#define picobase_det_utf8_length(x) ( ((x)<(picoos_uint8)'\200')?1:(((x)>=(picoos_uint8)'\370')?0:(((x)>=(picoos_uint8)'\360')?4:(((x)>=(picoos_uint8)'\340')?3:(((x)>=(picoos_uint8)'\300')?2:0)))) )
|
||||
|
||||
/**
|
||||
* Converts the content of 'utf8str' to lowercase and stores it on 'lowercase'
|
||||
* on the first byte of the UTF8 character
|
||||
* @param utf8str : utf8 string
|
||||
* @param lowercaseMaxLen : maximal number of bytes available in 'lowercase'
|
||||
* @param lowercase : string converted to lowercase (output)
|
||||
* @param done : flag to report success/failure of the operation (output)
|
||||
* @return TRUE if successful, FALSE otherwise
|
||||
*/
|
||||
picoos_int32 picobase_lowercase_utf8_str (picoos_uchar utf8str[], picoos_char lowercase[], picoos_int32 lowercaseMaxLen, picoos_uint8 * done);
|
||||
|
||||
/**
|
||||
* Converts the content of 'utf8str' to upperrcase and stores it on 'uppercase'
|
||||
* @param utf8str : utf8 string
|
||||
* @param uppercase : string converted to uppercase (output)
|
||||
* @param uppercaseMaxLen : maximal number of bytes available in 'uppercase'
|
||||
* @param done : flag to report success/failure of the operation (output)
|
||||
* @return TRUE if successful, FALSE otherwise
|
||||
*/
|
||||
picoos_int32 picobase_uppercase_utf8_str (picoos_uchar utf8str[], picoos_char uppercase[], int uppercaseMaxLen, picoos_uint8 * done);
|
||||
|
||||
/**
|
||||
* Gets next UTF8 character 'utf8char' from the UTF8 string
|
||||
* 'utf8s' starting at position 'pos'
|
||||
* @param utf8s : UTF8 string
|
||||
* @param utf8slenmax : max length accessible in utf8s
|
||||
* @param pos : position from where the UTF8 character is checked and copied
|
||||
* (set also as output to the position directly following the UTF8 char)
|
||||
* @param utf8char : zero terminated UTF8 character containing 1 to 4 bytes (output)
|
||||
* @return TRUE if okay
|
||||
* @return FALSE if there is no valid UTF8 char or no more UTF8 char available within utf8len
|
||||
*/
|
||||
picoos_uint8 picobase_get_next_utf8char(const picoos_uint8 *utf8s,
|
||||
const picoos_uint32 utf8slenmax,
|
||||
picoos_uint32 *pos,
|
||||
picobase_utf8char utf8char);
|
||||
|
||||
/**
|
||||
* Same as picobase_get_next_utf8char
|
||||
* without copying the char to utf8char
|
||||
*/
|
||||
picoos_uint8 picobase_get_next_utf8charpos(const picoos_uint8 *utf8s,
|
||||
const picoos_uint32 utf8slenmax,
|
||||
picoos_uint32 *pos);
|
||||
|
||||
/**
|
||||
* Gets previous UTF8 character 'utf8char' from the UTF8 string
|
||||
* 'utf8s' starting the backward search at position 'pos-1'
|
||||
* @param utf8s : UTF8 string
|
||||
* @param utf8slenmin : min length accessible in utf8s
|
||||
* @param pos : the search for the prev UTF8 char starts at [pos-1]
|
||||
* (set also as output to the start position of the prev UTF8 character)
|
||||
* @param utf8char : zero terminated UTF8 character containing 1 to 4 bytes (output)
|
||||
* @return TRUE if okay
|
||||
* @return FALSE if there is no valid UTF8 char preceeding pos or no more UTF8 char available within utf8len
|
||||
*/
|
||||
picoos_uint8 picobase_get_prev_utf8char(const picoos_uint8 *utf8s,
|
||||
const picoos_uint32 utf8slenmin,
|
||||
picoos_uint32 *pos,
|
||||
picobase_utf8char utf8char);
|
||||
|
||||
/**
|
||||
* Same as picobase_get_prev_utf8char
|
||||
* without copying the char to utf8char
|
||||
*/
|
||||
picoos_uint8 picobase_get_prev_utf8charpos(const picoos_uint8 *utf8s,
|
||||
const picoos_uint32 utf8slenmin,
|
||||
picoos_uint32 *pos);
|
||||
|
||||
|
||||
/**
|
||||
* returns TRUE if the input string is UTF8 and uppercase
|
||||
* @param str : UTF8 string
|
||||
* @param strmaxlen : max length for the input string
|
||||
* @return TRUE if string is UTF8 and uppercase
|
||||
* @return FALSE otherwise
|
||||
*/
|
||||
extern picoos_bool picobase_is_utf8_uppercase (picoos_uchar str[], picoos_int32 strmaxlen);
|
||||
|
||||
/**
|
||||
* returns TRUE if the input string is UTF8 and lowercase
|
||||
* @param str : UTF8 string
|
||||
* @param strmaxlen : max length for the input string
|
||||
* @return TRUE if string is UTF8 and lowercase
|
||||
* @return FALSE otherwise
|
||||
*/
|
||||
extern picoos_bool picobase_is_utf8_lowercase (picoos_uchar str[], picoos_int32 strmaxlen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*PICOBASE_H_*/
|
||||
+2028
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picocep.h
|
||||
*
|
||||
* Cepstral Smoothing PU - Header file
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PICOCEP_H_
|
||||
#define PICOCEP_H_
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picodata.h"
|
||||
#include "picorsrc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ******************************************************************************
|
||||
* items related to the generic interface
|
||||
********************************************************************************/
|
||||
picodata_ProcessingUnit picocep_newCepUnit(picoos_MemoryManager mm,
|
||||
picoos_Common common, picodata_CharBuffer cbIn,
|
||||
picodata_CharBuffer cbOut, picorsrc_Voice voice);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*PICOCEP_H_*/
|
||||
@@ -0,0 +1,840 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picoctrl.c
|
||||
*
|
||||
* Control PU -- Implementation
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
#include "picodefs.h"
|
||||
#include "picoos.h"
|
||||
#include "picodbg.h"
|
||||
#include "picodata.h"
|
||||
#include "picorsrc.h"
|
||||
|
||||
/* processing unit definitions */
|
||||
#include "picotok.h"
|
||||
#include "picopr.h"
|
||||
#include "picowa.h"
|
||||
#include "picosa.h"
|
||||
#include "picoacph.h"
|
||||
#include "picospho.h"
|
||||
#include "picopam.h"
|
||||
#include "picocep.h"
|
||||
#include "picosig.h"
|
||||
#if defined(PICO_DEVEL_MODE)
|
||||
#include "../history/picosink.h"
|
||||
#endif
|
||||
|
||||
#include "picoctrl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup picoctrl
|
||||
* @b Control
|
||||
* The "control" is a processing unit (PU) that contains and governs a sequence of sub-PUs
|
||||
* (TTS processing chain).
|
||||
* At each step (ctrlStep) it passes control to one of the sub-PUs (currrent PU). It may re-assign
|
||||
* the role of "current PU" to another sub-PU, according to the status information returned from each PU.
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------
|
||||
* object : Control
|
||||
* shortcut : ctrl
|
||||
* derived from : picodata_ProcessingUnit
|
||||
* implements a ProcessingUnit by creating and controlling
|
||||
* a sequence of Processing Units (of possibly different
|
||||
* implementations) exchanging data via CharBuffers
|
||||
* ---------------------------------------------------------*/
|
||||
/* control sub-object */
|
||||
typedef struct ctrl_subobj {
|
||||
picoos_uint8 numProcUnits;
|
||||
picoos_uint8 curPU;
|
||||
picoos_uint8 lastItemTypeProduced;
|
||||
picodata_ProcessingUnit procUnit [PICOCTRL_MAX_PROC_UNITS];
|
||||
picodata_step_result_t procStatus [PICOCTRL_MAX_PROC_UNITS];
|
||||
picodata_CharBuffer procCbOut [PICOCTRL_MAX_PROC_UNITS];
|
||||
} ctrl_subobj_t;
|
||||
|
||||
/**
|
||||
* performs Control PU initialization
|
||||
* @param this : pointer to Control PU
|
||||
* @return PICO_OK : processing done
|
||||
* @return PICO_ERR_OTHER : init error
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
static pico_status_t ctrlInitialize(register picodata_ProcessingUnit this, picoos_int32 resetMode) {
|
||||
register ctrl_subobj_t * ctrl;
|
||||
pico_status_t status= PICO_OK;
|
||||
picoos_int8 i;
|
||||
|
||||
if (NULL == this || NULL == this->subObj) {
|
||||
return PICO_ERR_OTHER;
|
||||
}
|
||||
ctrl = (ctrl_subobj_t *) this->subObj;
|
||||
ctrl->curPU = 0;
|
||||
ctrl->lastItemTypeProduced=0; /*no item produced by default*/
|
||||
status = PICO_OK;
|
||||
for (i = 0; i < ctrl->numProcUnits; i++) {
|
||||
if (PICO_OK == status) {
|
||||
status = ctrl->procUnit[i]->initialize(ctrl->procUnit[i], resetMode);
|
||||
PICODBG_DEBUG(("(re-)initializing procUnit[%i] returned status %i",i, status));
|
||||
}
|
||||
if (PICO_OK == status) {
|
||||
status = picodata_cbReset(ctrl->procCbOut[i]);
|
||||
PICODBG_DEBUG(("(re-)initializing procCbOut[%i] returned status %i",i, status));
|
||||
}
|
||||
}
|
||||
if (PICO_OK != status) {
|
||||
picoos_emRaiseException(this->common->em,status,NULL,(picoos_char*)"problem (re-)initializing the engine");
|
||||
}
|
||||
return status;
|
||||
}/*ctrlInitialize*/
|
||||
|
||||
|
||||
/**
|
||||
* performs one processing step
|
||||
* @param this : pointer to Control PU
|
||||
* @param mode : activation mode (unused)
|
||||
* @param bytesOutput : number of bytes produced during this step (output)
|
||||
* @return PICO_OK : processing done
|
||||
* @return PICO_EXC_OUT_OF_MEM : no more memory available
|
||||
* @return PICO_ERR_OTHER : other error
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
static picodata_step_result_t ctrlStep(register picodata_ProcessingUnit this,
|
||||
picoos_int16 mode, picoos_uint16 * bytesOutput) {
|
||||
/* rules/invariants:
|
||||
* - all pu's above current have status idle except possibly pu+1, which may be busy.
|
||||
* (The latter is set if any pu->step produced output)
|
||||
* - a pu returns idle iff its cbIn is empty and it has no more data ready for output */
|
||||
|
||||
register ctrl_subobj_t * ctrl = (ctrl_subobj_t *) this->subObj;
|
||||
picodata_step_result_t status;
|
||||
picoos_uint16 puBytesOutput;
|
||||
#if defined(PICO_DEVEL_MODE)
|
||||
picoos_uint8 btype;
|
||||
#endif
|
||||
|
||||
*bytesOutput = 0;
|
||||
ctrl->lastItemTypeProduced=0; /*no item produced by default*/
|
||||
|
||||
/* --------------------- */
|
||||
/* do step of current pu */
|
||||
/* --------------------- */
|
||||
status = ctrl->procStatus[ctrl->curPU] = ctrl->procUnit[ctrl->curPU]->step(
|
||||
ctrl->procUnit[ctrl->curPU], mode, &puBytesOutput);
|
||||
|
||||
if (puBytesOutput) {
|
||||
|
||||
#if defined(PICO_DEVEL_MODE)
|
||||
/*store the type of item produced*/
|
||||
btype = picodata_cbGetFrontItemType(ctrl->procUnit[ctrl->curPU]->cbOut);
|
||||
ctrl->lastItemTypeProduced=(picoos_uint8)btype;
|
||||
#endif
|
||||
|
||||
if (ctrl->curPU < ctrl->numProcUnits-1) {
|
||||
/* data was output to internal PU buffers : set following pu to busy */
|
||||
ctrl->procStatus[ctrl->curPU + 1] = PICODATA_PU_BUSY;
|
||||
} else {
|
||||
/* data was output to caller output buffer */
|
||||
*bytesOutput = puBytesOutput;
|
||||
}
|
||||
}
|
||||
/* recalculate state depending on pu status returned from curPU */
|
||||
switch (status) {
|
||||
case PICODATA_PU_ATOMIC:
|
||||
PICODBG_DEBUG(("got PICODATA_PU_ATOMIC"));
|
||||
return status;
|
||||
break;
|
||||
|
||||
case PICODATA_PU_BUSY:
|
||||
PICODBG_DEBUG(("got PICODATA_PU_BUSY"));
|
||||
if ( (ctrl->curPU+1 < ctrl->numProcUnits) && (PICODATA_PU_BUSY
|
||||
== ctrl->procStatus[ctrl->curPU+1])) {
|
||||
ctrl->curPU++;
|
||||
}
|
||||
return status;
|
||||
break;
|
||||
|
||||
case PICODATA_PU_IDLE:
|
||||
PICODBG_DEBUG(("got PICODATA_PU_IDLE"));
|
||||
if ( (ctrl->curPU+1 < ctrl->numProcUnits) && (PICODATA_PU_BUSY
|
||||
== ctrl->procStatus[ctrl->curPU+1])) {
|
||||
/* still data to process below */
|
||||
ctrl->curPU++;
|
||||
} else if (0 == ctrl->curPU) { /* all pu's are idle */
|
||||
/* nothing to do */
|
||||
} else { /* find non-idle pu above */
|
||||
PICODBG_DEBUG((
|
||||
"find non-idle pu above from pu %d with status %d",
|
||||
ctrl->curPU, ctrl->procStatus[ctrl->curPU]));
|
||||
while ((ctrl->curPU > 0) && (PICODATA_PU_IDLE
|
||||
== ctrl->procStatus[ctrl->curPU])) {
|
||||
ctrl->curPU--;
|
||||
}
|
||||
ctrl->procStatus[ctrl->curPU] = PICODATA_PU_BUSY;
|
||||
}
|
||||
PICODBG_DEBUG(("going to pu %d with status %d",
|
||||
ctrl->curPU, ctrl->procStatus[ctrl->curPU]));
|
||||
/*update last scheduled PU*/
|
||||
return ctrl->procStatus[ctrl->curPU];
|
||||
break;
|
||||
|
||||
case PICODATA_PU_OUT_FULL:
|
||||
PICODBG_DEBUG(("got PICODATA_PU_OUT_FULL"));
|
||||
if (ctrl->curPU+1 < ctrl->numProcUnits) { /* let pu below empty buffer */
|
||||
ctrl->curPU++;
|
||||
ctrl->procStatus[ctrl->curPU] = PICODATA_PU_BUSY;
|
||||
} else {
|
||||
/* nothing more to do, out_full will be returned to caller */
|
||||
}
|
||||
return ctrl->procStatus[ctrl->curPU];
|
||||
break;
|
||||
default:
|
||||
return PICODATA_PU_ERROR;
|
||||
break;
|
||||
}
|
||||
}/*ctrlStep*/
|
||||
|
||||
/**
|
||||
* terminates Control PU
|
||||
* @param this : pointer to Control PU
|
||||
* @return PICO_OK : processing done
|
||||
* @return PICO_ERR_OTHER : other error
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
static pico_status_t ctrlTerminate(register picodata_ProcessingUnit this) {
|
||||
pico_status_t status = PICO_OK;
|
||||
picoos_int16 i;
|
||||
register ctrl_subobj_t * ctrl;
|
||||
if (NULL == this || NULL == this->subObj) {
|
||||
return PICO_ERR_OTHER;
|
||||
}
|
||||
ctrl = (ctrl_subobj_t *) this->subObj;
|
||||
for (i = 0; i < ctrl->numProcUnits; i++) {
|
||||
status = ctrl->procUnit[i]->terminate(ctrl->procUnit[i]);
|
||||
PICODBG_DEBUG(("terminating procUnit[%i] returned status %i",i, status));
|
||||
if (PICO_OK != status) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}/*ctrlTerminate*/
|
||||
|
||||
/**
|
||||
* deallocates Control PU's subobject
|
||||
* @param this : pointer to Control PU
|
||||
* @return PICO_OK : processing done
|
||||
* @return PICO_ERR_OTHER : other error
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
static pico_status_t ctrlSubObjDeallocate(register picodata_ProcessingUnit this,
|
||||
picoos_MemoryManager mm) {
|
||||
register ctrl_subobj_t * ctrl;
|
||||
picoos_int16 i;
|
||||
|
||||
if (NULL == this || NULL == this->subObj) {
|
||||
return PICO_ERR_OTHER;
|
||||
}
|
||||
ctrl = (ctrl_subobj_t *) this->subObj;
|
||||
mm = mm; /* fix warning "var not used in this function"*/
|
||||
/* deallocate members (procCbOut and procUnit) */
|
||||
for (i = ctrl->numProcUnits-1; i >= 0; i--) {
|
||||
picodata_disposeProcessingUnit(this->common->mm,&ctrl->procUnit[i]);
|
||||
picodata_disposeCharBuffer(this->common->mm, &ctrl->procCbOut[i]);
|
||||
}
|
||||
/* deallocate object itself */
|
||||
picoos_deallocate(this->common->mm, (void *) &this->subObj);
|
||||
|
||||
return PICO_OK;
|
||||
}/*ctrlSubObjDeallocate*/
|
||||
|
||||
/**
|
||||
* inserts a new PU in the TTS processing chain
|
||||
* @param this : pointer to Control PU
|
||||
* @param puType : type of the PU to be inserted
|
||||
* @param last : if true, inserted PU is the last in the TTS processing chain
|
||||
* @return PICO_OK : processing done
|
||||
* @return PICO_EXC_OUT_OF_MEM : no more memory available
|
||||
* @return PICO_ERR_OTHER : other error
|
||||
* @remarks Calls the PU object creation method
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
static pico_status_t ctrlAddPU(register picodata_ProcessingUnit this,
|
||||
picodata_putype_t puType,
|
||||
picoos_bool levelAwareCbOut,
|
||||
picoos_bool last)
|
||||
{
|
||||
picoos_uint16 bufSize;
|
||||
register ctrl_subobj_t * ctrl;
|
||||
picodata_CharBuffer cbIn;
|
||||
picoos_uint8 newPU;
|
||||
if (this == NULL) {
|
||||
return PICO_ERR_OTHER;
|
||||
}
|
||||
ctrl = (ctrl_subobj_t *) this->subObj;
|
||||
if (ctrl == NULL) {
|
||||
return PICO_ERR_OTHER;
|
||||
}
|
||||
newPU = ctrl->numProcUnits;
|
||||
if (0 == newPU) {
|
||||
PICODBG_DEBUG(("taking cbIn of this because adding first pu"));
|
||||
cbIn = this->cbIn;
|
||||
} else {
|
||||
PICODBG_DEBUG(("taking cbIn of previous pu"));
|
||||
cbIn = ctrl->procCbOut[newPU-1];
|
||||
}
|
||||
if (last) {
|
||||
PICODBG_DEBUG(("taking cbOut of this because adding last pu"));
|
||||
ctrl->procCbOut[newPU] = this->cbOut;
|
||||
} else {
|
||||
PICODBG_DEBUG(("creating intermediate cbOut of pu[%i]", newPU));
|
||||
bufSize = picodata_get_default_buf_size(puType);
|
||||
ctrl->procCbOut[newPU] = picodata_newCharBuffer(this->common->mm,
|
||||
this->common,bufSize);
|
||||
|
||||
PICODBG_DEBUG(("intermediate cbOut of pu[%i] (address %i)", newPU,
|
||||
(picoos_uint32) ctrl->procCbOut[newPU]));
|
||||
if (NULL == ctrl->procCbOut[newPU]) {
|
||||
return PICO_EXC_OUT_OF_MEM;
|
||||
}
|
||||
}
|
||||
ctrl->procStatus[newPU] = PICODATA_PU_IDLE;
|
||||
/*...............*/
|
||||
switch (puType) {
|
||||
case PICODATA_PUTYPE_TOK:
|
||||
PICODBG_DEBUG(("creating TokenizeUnit for pu %i", newPU));
|
||||
ctrl->procUnit[newPU] = picotok_newTokenizeUnit(this->common->mm,
|
||||
this->common, cbIn, ctrl->procCbOut[newPU], this->voice);
|
||||
break;
|
||||
case PICODATA_PUTYPE_PR:
|
||||
PICODBG_DEBUG(("creating PreprocUnit for pu %i", newPU));
|
||||
ctrl->procUnit[newPU] = picopr_newPreprocUnit(this->common->mm,
|
||||
this->common, cbIn, ctrl->procCbOut[newPU], this->voice);
|
||||
break;
|
||||
case PICODATA_PUTYPE_WA:
|
||||
PICODBG_DEBUG(("creating WordAnaUnit for pu %i", newPU));
|
||||
ctrl->procUnit[newPU] = picowa_newWordAnaUnit(this->common->mm,
|
||||
this->common, cbIn, ctrl->procCbOut[newPU], this->voice);
|
||||
break;
|
||||
case PICODATA_PUTYPE_SA:
|
||||
PICODBG_DEBUG(("creating SentAnaUnit for pu %i", newPU));
|
||||
ctrl->procUnit[newPU] = picosa_newSentAnaUnit(this->common->mm,
|
||||
this->common, cbIn, ctrl->procCbOut[newPU], this->voice);
|
||||
break;
|
||||
case PICODATA_PUTYPE_ACPH:
|
||||
PICODBG_DEBUG(("creating AccPhrUnit for pu %i", newPU));
|
||||
ctrl->procUnit[newPU] = picoacph_newAccPhrUnit(this->common->mm,
|
||||
this->common, cbIn, ctrl->procCbOut[newPU], this->voice);
|
||||
break;
|
||||
case PICODATA_PUTYPE_SPHO:
|
||||
PICODBG_DEBUG(("creating SentPhoUnit for pu %i", newPU));
|
||||
ctrl->procUnit[newPU] = picospho_newSentPhoUnit(this->common->mm,
|
||||
this->common, cbIn, ctrl->procCbOut[newPU], this->voice);
|
||||
break;
|
||||
case PICODATA_PUTYPE_PAM:
|
||||
PICODBG_DEBUG(("creating PAMUnit for pu %i", newPU));
|
||||
ctrl->procUnit[newPU] = picopam_newPamUnit(this->common->mm,
|
||||
this->common, cbIn, ctrl->procCbOut[newPU], this->voice);
|
||||
break;
|
||||
case PICODATA_PUTYPE_CEP:
|
||||
PICODBG_DEBUG(("creating CepUnit for pu %i", newPU));
|
||||
ctrl->procUnit[newPU] = picocep_newCepUnit(this->common->mm,
|
||||
this->common, cbIn, ctrl->procCbOut[newPU], this->voice);
|
||||
break;
|
||||
#if defined(PICO_DEVEL_MODE)
|
||||
case PICODATA_PUTYPE_SINK:
|
||||
PICODBG_DEBUG(("creating SigUnit for pu %i", newPU));
|
||||
ctrl->procUnit[newPU] = picosink_newSinkUnit(this->common->mm,
|
||||
this->common, cbIn, ctrl->procCbOut[newPU], this->voice);
|
||||
break;
|
||||
#endif
|
||||
case PICODATA_PUTYPE_SIG:
|
||||
PICODBG_DEBUG(("creating SigUnit for pu %i", newPU));
|
||||
ctrl->procUnit[newPU] = picosig_newSigUnit(this->common->mm,
|
||||
this->common, cbIn, ctrl->procCbOut[newPU], this->voice);
|
||||
break;
|
||||
default:
|
||||
ctrl->procUnit[newPU] = picodata_newProcessingUnit(
|
||||
this->common->mm, this->common, cbIn,
|
||||
ctrl->procCbOut[newPU], this->voice);
|
||||
break;
|
||||
}
|
||||
if (NULL == ctrl->procUnit[newPU]) {
|
||||
picodata_disposeCharBuffer(this->common->mm,&ctrl->procCbOut[newPU]);
|
||||
return PICO_EXC_OUT_OF_MEM;
|
||||
}
|
||||
ctrl->numProcUnits++;
|
||||
return PICO_OK;
|
||||
}/*ctrlAddPU*/
|
||||
|
||||
/*forward declaration : see below for full function body*/
|
||||
void picoctrl_disposeControl(picoos_MemoryManager mm,
|
||||
picodata_ProcessingUnit * this);
|
||||
|
||||
/**
|
||||
* initializes a control PU object
|
||||
* @param mm : memory manager
|
||||
* @param common : the common object
|
||||
* @param cbIn : the input char buffer
|
||||
* @param cbOut : the output char buffer
|
||||
* @param voice : the voice object
|
||||
* @return the pointer to the PU object created if OK
|
||||
* @return PICO_EXC_OUT_OF_MEM : no more memory available
|
||||
* @return NULL otherwise
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
picodata_ProcessingUnit picoctrl_newControl(picoos_MemoryManager mm,
|
||||
picoos_Common common, picodata_CharBuffer cbIn,
|
||||
picodata_CharBuffer cbOut, picorsrc_Voice voice) {
|
||||
picoos_int16 i;
|
||||
register ctrl_subobj_t * ctrl;
|
||||
picodata_ProcessingUnit this = picodata_newProcessingUnit(mm, common, cbIn,
|
||||
cbOut,voice);
|
||||
if (this == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this->initialize = ctrlInitialize;
|
||||
this->step = ctrlStep;
|
||||
this->terminate = ctrlTerminate;
|
||||
this->subDeallocate = ctrlSubObjDeallocate;
|
||||
|
||||
this->subObj = picoos_allocate(mm, sizeof(ctrl_subobj_t));
|
||||
if (this->subObj == NULL) {
|
||||
picoos_deallocate(mm, (void **)(void*)&this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctrl = (ctrl_subobj_t *) this->subObj;
|
||||
|
||||
for (i=0; i < PICOCTRL_MAX_PROC_UNITS; i++) {
|
||||
ctrl->procUnit[i] = NULL;
|
||||
ctrl->procStatus[i] = PICODATA_PU_IDLE;
|
||||
ctrl->procCbOut[i] = NULL;
|
||||
}
|
||||
ctrl->numProcUnits = 0;
|
||||
|
||||
if (
|
||||
(PICO_OK == ctrlAddPU(this,PICODATA_PUTYPE_TOK, FALSE, /*last*/FALSE)) &&
|
||||
(PICO_OK == ctrlAddPU(this,PICODATA_PUTYPE_PR, FALSE, FALSE)) &&
|
||||
(PICO_OK == ctrlAddPU(this,PICODATA_PUTYPE_WA, FALSE, FALSE)) &&
|
||||
(PICO_OK == ctrlAddPU(this,PICODATA_PUTYPE_SA, FALSE, FALSE)) &&
|
||||
(PICO_OK == ctrlAddPU(this,PICODATA_PUTYPE_ACPH, FALSE, FALSE)) &&
|
||||
(PICO_OK == ctrlAddPU(this,PICODATA_PUTYPE_SPHO, FALSE, FALSE)) &&
|
||||
(PICO_OK == ctrlAddPU(this,PICODATA_PUTYPE_PAM, FALSE, FALSE)) &&
|
||||
(PICO_OK == ctrlAddPU(this,PICODATA_PUTYPE_CEP, FALSE, FALSE)) &&
|
||||
(PICO_OK == ctrlAddPU(this,PICODATA_PUTYPE_SIG, FALSE, TRUE))
|
||||
) {
|
||||
|
||||
/* we don't call ctrlInitialize here because ctrlAddPU does initialize the PUs allready and the only thing
|
||||
* remaining to initialize is:
|
||||
*/
|
||||
ctrl->curPU = 0;
|
||||
return this;
|
||||
} else {
|
||||
picoctrl_disposeControl(this->common->mm,&this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}/*picoctrl_newControl*/
|
||||
|
||||
/**
|
||||
* disposes a Control PU
|
||||
* @param mm : memory manager
|
||||
* @param this : pointer to Control PU
|
||||
*
|
||||
* @return void
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
void picoctrl_disposeControl(picoos_MemoryManager mm,
|
||||
picodata_ProcessingUnit * this)
|
||||
{
|
||||
picodata_disposeProcessingUnit(mm, this);
|
||||
}/*picoctrl_disposeControl*/
|
||||
|
||||
/* **************************************************************************
|
||||
*
|
||||
* Engine
|
||||
*
|
||||
****************************************************************************/
|
||||
/** object : Engine
|
||||
* shortcut : eng
|
||||
*/
|
||||
typedef struct picoctrl_engine {
|
||||
picoos_uint32 magic; /* magic number used to validate handles */
|
||||
void *raw_mem;
|
||||
picoos_Common common;
|
||||
picorsrc_Voice voice;
|
||||
picodata_ProcessingUnit control;
|
||||
picodata_CharBuffer cbIn, cbOut;
|
||||
} picoctrl_engine_t;
|
||||
|
||||
|
||||
#define MAGIC_MASK 0x5069436F /* PiCo */
|
||||
|
||||
#define SET_MAGIC_NUMBER(eng) \
|
||||
(eng)->magic = ((picoos_uint32) (uintptr_t) (eng)) ^ MAGIC_MASK
|
||||
|
||||
#define CHECK_MAGIC_NUMBER(eng) \
|
||||
((eng)->magic == (((picoos_uint32) (uintptr_t) (eng)) ^ MAGIC_MASK))
|
||||
|
||||
/**
|
||||
* performs an engine reset
|
||||
* @param this : the engine object
|
||||
* @return PICO_OK : reset performed
|
||||
* @return otherwise error code
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
pico_status_t picoctrl_engReset(picoctrl_Engine this, picoos_int32 resetMode)
|
||||
{
|
||||
pico_status_t status;
|
||||
|
||||
if (NULL == this) {
|
||||
return PICO_ERR_NULLPTR_ACCESS;
|
||||
}
|
||||
picoos_emReset(this->common->em);
|
||||
|
||||
status = this->control->terminate(this->control);
|
||||
if (PICO_OK == status) {
|
||||
status = this->control->initialize(this->control, resetMode);
|
||||
}
|
||||
if (PICO_OK == status) {
|
||||
status = picodata_cbReset(this->cbIn);
|
||||
}
|
||||
if (PICO_OK == status) {
|
||||
status = picodata_cbReset(this->cbOut);
|
||||
}
|
||||
if (PICO_OK != status) {
|
||||
picoos_emRaiseException(this->common->em,status,NULL,(picoos_char*) "problem resetting engine");
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks an engine handle
|
||||
* @param this : the engine object
|
||||
* @return PICO_OK : reset performed
|
||||
* @return non-zero if 'this' is a valid engine handle
|
||||
* @return zero otherwise
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
picoos_int16 picoctrl_isValidEngineHandle(picoctrl_Engine this)
|
||||
{
|
||||
return (this != NULL) && CHECK_MAGIC_NUMBER(this);
|
||||
}/*picoctrl_isValidEngineHandle*/
|
||||
|
||||
/**
|
||||
* creates a new engine object
|
||||
* @param mm : memory manager to be used for this engine
|
||||
* @param rm : resource manager to be used for this engine
|
||||
* @param voiceName : voice definition to be used for this engine
|
||||
* @return PICO_OK : reset performed
|
||||
* @return new engine handle
|
||||
* @return NULL otherwise
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
picoctrl_Engine picoctrl_newEngine(picoos_MemoryManager mm,
|
||||
picorsrc_ResourceManager rm, const picoos_char * voiceName) {
|
||||
picoos_uint8 done= TRUE;
|
||||
|
||||
picoos_uint16 bSize;
|
||||
|
||||
picoos_MemoryManager engMM;
|
||||
picoos_ExceptionManager engEM;
|
||||
|
||||
picoctrl_Engine this = (picoctrl_Engine) picoos_allocate(mm, sizeof(*this));
|
||||
|
||||
PICODBG_DEBUG(("creating engine for voice '%s'",voiceName));
|
||||
|
||||
done = (NULL != this);
|
||||
|
||||
if (done) {
|
||||
this->magic = 0;
|
||||
this->common = NULL;
|
||||
this->voice = NULL;
|
||||
this->control = NULL;
|
||||
this->cbIn = NULL;
|
||||
this->cbOut = NULL;
|
||||
|
||||
this->raw_mem = picoos_allocate(mm, PICOCTRL_DEFAULT_ENGINE_SIZE);
|
||||
if (NULL == this->raw_mem) {
|
||||
done = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (done) {
|
||||
engMM = picoos_newMemoryManager(this->raw_mem, PICOCTRL_DEFAULT_ENGINE_SIZE,
|
||||
/*enableMemProt*/ FALSE);
|
||||
done = (NULL != engMM);
|
||||
}
|
||||
if (done) {
|
||||
this->common = picoos_newCommon(engMM);
|
||||
engEM = picoos_newExceptionManager(engMM);
|
||||
done = (NULL != this->common) && (NULL != engEM);
|
||||
}
|
||||
if (done) {
|
||||
this->common->mm = engMM;
|
||||
this->common->em = engEM;
|
||||
|
||||
done = (PICO_OK == picorsrc_createVoice(rm,voiceName,&(this->voice)));
|
||||
}
|
||||
if (done) {
|
||||
bSize = picodata_get_default_buf_size(PICODATA_PUTYPE_TEXT);
|
||||
|
||||
this->cbIn = picodata_newCharBuffer(this->common->mm,
|
||||
this->common, bSize);
|
||||
bSize = picodata_get_default_buf_size(PICODATA_PUTYPE_SIG);
|
||||
|
||||
this->cbOut = picodata_newCharBuffer(this->common->mm,
|
||||
this->common, bSize);
|
||||
|
||||
PICODBG_DEBUG(("cbOut has address %i", (picoos_uint32) this->cbOut));
|
||||
|
||||
|
||||
this->control = picoctrl_newControl(this->common->mm, this->common,
|
||||
this->cbIn, this->cbOut, this->voice);
|
||||
done = (NULL != this->cbIn) && (NULL != this->cbOut)
|
||||
&& (NULL != this->control);
|
||||
}
|
||||
if (done) {
|
||||
SET_MAGIC_NUMBER(this);
|
||||
} else {
|
||||
if (NULL != this) {
|
||||
if (NULL != this->voice) {
|
||||
picorsrc_releaseVoice(rm,&(this->voice));
|
||||
}
|
||||
if(NULL != this->raw_mem) {
|
||||
picoos_deallocate(mm,&(this->raw_mem));
|
||||
}
|
||||
picoos_deallocate(mm,(void *)&this);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}/*picoctrl_newEngine*/
|
||||
|
||||
/**
|
||||
* disposes an engine object
|
||||
* @param mm : memory manager associated to the engine
|
||||
* @param rm : resource manager associated to the engine
|
||||
* @param this : handle of the engine to dispose
|
||||
* @return PICO_OK : reset performed
|
||||
* @return void
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
void picoctrl_disposeEngine(picoos_MemoryManager mm, picorsrc_ResourceManager rm,
|
||||
picoctrl_Engine * this)
|
||||
{
|
||||
if (NULL != (*this)) {
|
||||
if (NULL != (*this)->voice) {
|
||||
picorsrc_releaseVoice(rm,&((*this)->voice));
|
||||
}
|
||||
if(NULL != (*this)->control) {
|
||||
picoctrl_disposeControl((*this)->common->mm,&((*this)->control));
|
||||
}
|
||||
if(NULL != (*this)->raw_mem) {
|
||||
picoos_deallocate(mm,&((*this)->raw_mem));
|
||||
}
|
||||
(*this)->magic ^= 0xFFFEFDFC;
|
||||
picoos_deallocate(mm,(void **)this);
|
||||
}
|
||||
}/*picoctrl_disposeEngine*/
|
||||
|
||||
/**
|
||||
* resets the exception manager of an engine
|
||||
* @param this : handle of the engine
|
||||
* @return void
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
void picoctrl_engResetExceptionManager(
|
||||
picoctrl_Engine this
|
||||
)
|
||||
{
|
||||
picoos_emReset(this->common->em);
|
||||
}/*picoctrl_engResetExceptionManager*/
|
||||
|
||||
/**
|
||||
* returns the engine common pointer
|
||||
* @param this : handle of the engine
|
||||
* @return PICO_OK : reset performed
|
||||
* @return the engine common pointer
|
||||
* @return NULL if error
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
picoos_Common picoctrl_engGetCommon(picoctrl_Engine this) {
|
||||
if (NULL == this) {
|
||||
return NULL;
|
||||
} else {
|
||||
return this->common;
|
||||
}
|
||||
}/*picoctrl_engGetCommon*/
|
||||
|
||||
/**
|
||||
* feed raw 'text' into 'engine'. text may contain '\\0'.
|
||||
* @param this : handle of the engine
|
||||
* @param text : the input text
|
||||
* @param textSize : size of the input text
|
||||
* @param *bytesPut : the number of bytes effectively consumed from 'text'.
|
||||
* @return PICO_OK : feeding succeded
|
||||
* @return PICO_ERR_OTHER : if error
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
pico_status_t picoctrl_engFeedText(picoctrl_Engine this,
|
||||
picoos_char * text,
|
||||
picoos_int16 textSize, picoos_int16 * bytesPut) {
|
||||
if (NULL == this) {
|
||||
return PICO_ERR_OTHER;
|
||||
}
|
||||
PICODBG_DEBUG(("get \"%.100s\"", text));
|
||||
*bytesPut = 0;
|
||||
while ((*bytesPut < textSize) && (PICO_OK == picodata_cbPutCh(this->cbIn, text[*bytesPut]))) {
|
||||
(*bytesPut)++;
|
||||
}
|
||||
|
||||
return PICO_OK;
|
||||
}/*picoctrl_engFeedText*/
|
||||
|
||||
/**
|
||||
* gets engine output bytes
|
||||
* @param this : handle of the engine
|
||||
* @param buffer : the destination buffer
|
||||
* @param bufferSize : max size of the destinatioon buffer
|
||||
* @param *bytesReceived : the number of bytes effectively returned
|
||||
* @return PICO_OK : feeding succeded
|
||||
* @return PICO_ERR_OTHER : if error
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
picodata_step_result_t picoctrl_engFetchOutputItemBytes(
|
||||
picoctrl_Engine this,
|
||||
picoos_char *buffer,
|
||||
picoos_int16 bufferSize,
|
||||
picoos_int16 *bytesReceived) {
|
||||
picoos_uint16 ui;
|
||||
picodata_step_result_t stepResult;
|
||||
pico_status_t rv;
|
||||
|
||||
if (NULL == this) {
|
||||
return (picodata_step_result_t)PICO_STEP_ERROR;
|
||||
}
|
||||
PICODBG_DEBUG(("doing one step"));
|
||||
stepResult = this->control->step(this->control,/* mode */0,&ui);
|
||||
if (PICODATA_PU_ERROR != stepResult) {
|
||||
PICODBG_TRACE(("filling output buffer"));
|
||||
rv = picodata_cbGetSpeechData(this->cbOut, (picoos_uint8 *)buffer,
|
||||
bufferSize, &ui);
|
||||
|
||||
if (ui > 255) { /* because picoapi uses signed int16 */
|
||||
return (picodata_step_result_t)PICO_STEP_ERROR;
|
||||
} else {
|
||||
*bytesReceived = ui;
|
||||
}
|
||||
if ((rv == PICO_EXC_BUF_UNDERFLOW) || (rv == PICO_EXC_BUF_OVERFLOW)) {
|
||||
PICODBG_ERROR(("problem getting speech data"));
|
||||
return (picodata_step_result_t)PICO_STEP_ERROR;
|
||||
}
|
||||
/* rv must now be PICO_OK or PICO_EOF */
|
||||
PICODBG_ASSERT(((PICO_EOF == rv) || (PICO_OK == rv)));
|
||||
if ((PICODATA_PU_IDLE == stepResult) && (PICO_EOF == rv)) {
|
||||
PICODBG_DEBUG(("IDLE"));
|
||||
return (picodata_step_result_t)PICO_STEP_IDLE;
|
||||
} else if (PICODATA_PU_ERROR == stepResult) {
|
||||
PICODBG_DEBUG(("ERROR"));
|
||||
return (picodata_step_result_t)PICO_STEP_ERROR;
|
||||
} else {
|
||||
PICODBG_DEBUG(("BUSY"));
|
||||
return (picodata_step_result_t)PICO_STEP_BUSY;
|
||||
}
|
||||
} else {
|
||||
return (picodata_step_result_t)PICO_STEP_ERROR;
|
||||
}
|
||||
}/*picoctrl_engFetchOutputItemBytes*/
|
||||
|
||||
/**
|
||||
* returns the last scheduled PU
|
||||
* @param this : handle of the engine
|
||||
* @return a value >= 0 : last scheduled PU index
|
||||
* @remarks designed to be used for performance evaluation
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
picodata_step_result_t picoctrl_getLastScheduledPU(
|
||||
picoctrl_Engine this
|
||||
)
|
||||
{
|
||||
ctrl_subobj_t * ctrl;
|
||||
if (NULL == this || NULL == this->control->subObj) {
|
||||
return PICO_ERR_OTHER;
|
||||
}
|
||||
ctrl = (ctrl_subobj_t *) ((*this).control->subObj);
|
||||
return (picodata_step_result_t) ctrl->curPU;
|
||||
}/*picoctrl_getLastScheduledPU*/
|
||||
|
||||
/**
|
||||
* returns the last item type produced by the last scheduled PU
|
||||
* @param this : handle of the engine
|
||||
* @return a value >= 0 : item type (see picodata.h for item types)
|
||||
* @return a value = 0 : no item produced
|
||||
* @remarks designed to be used for performance evaluation
|
||||
* @callgraph
|
||||
* @callergraph
|
||||
*/
|
||||
picodata_step_result_t picoctrl_getLastProducedItemType(
|
||||
picoctrl_Engine this
|
||||
)
|
||||
{
|
||||
ctrl_subobj_t * ctrl;
|
||||
if (NULL == this || NULL == this->control->subObj) {
|
||||
return PICO_ERR_OTHER;
|
||||
}
|
||||
ctrl = (ctrl_subobj_t *) ((*this).control->subObj);
|
||||
return (picodata_step_result_t) ctrl->lastItemTypeProduced;
|
||||
}/*picoctrl_getLastProducedItemType*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Picoctrl.c end */
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picoctrl.h
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PICOCTRL_H_
|
||||
#define PICOCTRL_H_
|
||||
|
||||
#include "picodefs.h"
|
||||
#include "picoos.h"
|
||||
#include "picorsrc.h"
|
||||
#include "picodata.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
#define PICOCTRL_MAX_PROC_UNITS 25
|
||||
|
||||
/* temporarily increased for preprocessing
|
||||
#define PICOCTRL_DEFAULT_ENGINE_SIZE 200000
|
||||
*/
|
||||
#define PICOCTRL_DEFAULT_ENGINE_SIZE 1000000
|
||||
|
||||
typedef struct picoctrl_engine * picoctrl_Engine;
|
||||
|
||||
picoos_int16 picoctrl_isValidEngineHandle(picoctrl_Engine this);
|
||||
|
||||
picoctrl_Engine picoctrl_newEngine (
|
||||
picoos_MemoryManager mm,
|
||||
picorsrc_ResourceManager rm,
|
||||
const picoos_char * voiceName
|
||||
);
|
||||
|
||||
void picoctrl_disposeEngine(
|
||||
picoos_MemoryManager mm,
|
||||
picorsrc_ResourceManager rm,
|
||||
picoctrl_Engine * this
|
||||
);
|
||||
|
||||
pico_status_t picoctrl_engFeedText(
|
||||
picoctrl_Engine engine,
|
||||
picoos_char * text,
|
||||
picoos_int16 textSize,
|
||||
picoos_int16 * bytesPut);
|
||||
|
||||
pico_status_t picoctrl_engReset(
|
||||
picoctrl_Engine engine,
|
||||
picoos_int32 resetMode);
|
||||
|
||||
picoos_Common picoctrl_engGetCommon(picoctrl_Engine this);
|
||||
|
||||
picodata_step_result_t picoctrl_engFetchOutputItemBytes(
|
||||
picoctrl_Engine engine,
|
||||
picoos_char * buffer,
|
||||
picoos_int16 bufferSize,
|
||||
picoos_int16 * bytesReceived
|
||||
);
|
||||
|
||||
void picoctrl_engResetExceptionManager(
|
||||
picoctrl_Engine this
|
||||
);
|
||||
|
||||
|
||||
picodata_step_result_t picoctrl_getLastScheduledPU(
|
||||
picoctrl_Engine engine
|
||||
);
|
||||
|
||||
picodata_step_result_t picoctrl_getLastProducedItemType(
|
||||
picoctrl_Engine engine
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*PICOCTRL_H_*/
|
||||
+1155
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,643 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picodata.h
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
#ifndef PICODATA_H_
|
||||
#define PICODATA_H_
|
||||
|
||||
#include "picodefs.h"
|
||||
#include "picoos.h"
|
||||
#include "picotrns.h"
|
||||
#include "picokfst.h"
|
||||
#include "picorsrc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ***************************************************************
|
||||
* Constants *
|
||||
*****************************************************************/
|
||||
|
||||
#define PICODATA_MAX_ITEMS_PER_PHRASE 30
|
||||
|
||||
/**
|
||||
* @addtogroup picodata
|
||||
* <b> Pico Data : Item Format </b>\n
|
||||
*
|
||||
The item header is identical for all item types and PUs. Item types
|
||||
that are not handled by a PU are copied.
|
||||
|
||||
Item Header structure\n
|
||||
---------------------
|
||||
- Byte Content
|
||||
- 0x00 item type
|
||||
- 0x01 item info 1
|
||||
- 0x02 item info 2
|
||||
- 0x03 item length in bytes (not including the header)
|
||||
|
||||
depending on the item type/info, a specific subheader may follow
|
||||
(included in length)
|
||||
*/
|
||||
|
||||
/* item header fields (tmp.: use item functions below to acces header fields */
|
||||
#define PICODATA_ITEMIND_TYPE 0
|
||||
#define PICODATA_ITEMIND_INFO1 1
|
||||
#define PICODATA_ITEMIND_INFO2 2
|
||||
#define PICODATA_ITEMIND_LEN 3
|
||||
|
||||
/* ***************************************************************
|
||||
* CharBuffer *
|
||||
*****************************************************************/
|
||||
typedef struct picodata_char_buffer * picodata_CharBuffer;
|
||||
|
||||
picodata_CharBuffer picodata_newCharBuffer(picoos_MemoryManager mm,
|
||||
picoos_Common common, picoos_objsize_t size);
|
||||
|
||||
void picodata_disposeCharBuffer(picoos_MemoryManager mm,
|
||||
picodata_CharBuffer * this);
|
||||
|
||||
/* should not be used for PUs but only for feeding the initial cb */
|
||||
pico_status_t picodata_cbPutCh(register picodata_CharBuffer this, picoos_char ch);
|
||||
|
||||
/* should not be used for PUs other than first PU in the chain (picotok) */
|
||||
picoos_int16 picodata_cbGetCh(register picodata_CharBuffer this);
|
||||
|
||||
/* reset cb (as if after newCharBuffer) */
|
||||
pico_status_t picodata_cbReset (register picodata_CharBuffer this);
|
||||
|
||||
/* ** CharBuffer item functions, cf. below in items section ****/
|
||||
|
||||
/* ***************************************************************
|
||||
* items *
|
||||
*****************************************************************/
|
||||
|
||||
/* item header size */
|
||||
#define PICODATA_ITEM_HEADSIZE 4
|
||||
|
||||
typedef struct picodata_itemhead
|
||||
{
|
||||
picoos_uint8 type;
|
||||
picoos_uint8 info1;
|
||||
picoos_uint8 info2;
|
||||
picoos_uint8 len;
|
||||
} picodata_itemhead_t;
|
||||
|
||||
|
||||
/* -------------- System wide defines referred to by items -------- */
|
||||
/* ---- These maybe better stored in a knowledge module/resoruce*/
|
||||
#define PICODATA_ACC0 '\x30' /* 48 '0' */
|
||||
#define PICODATA_ACC1 '\x31' /* 49 '1' */
|
||||
#define PICODATA_ACC2 '\x32' /* 50 '2' */
|
||||
#define PICODATA_ACC3 '\x33' /* 51 '3' */
|
||||
#define PICODATA_ACC4 '\x34' /* 52 '4' */
|
||||
|
||||
/* reserved for future use:
|
||||
* user-imposed Part-Of-Speech ids for user lexica and phoneme tags
|
||||
* These values should be applied BEFORE POS-disambiguation. The POS lingware either assigns the same
|
||||
* ids to corresponding internal unique or composed POS or else the POS-D will consider these values
|
||||
* "default" */
|
||||
#define PICODATA_POS_XNPR 20
|
||||
#define PICODATA_POS_XN 21
|
||||
#define PICODATA_POS_XV 22
|
||||
#define PICODATA_POS_XA 23
|
||||
#define PICODATA_POS_XADV 24
|
||||
#define PICODATA_POS_XX 25
|
||||
|
||||
/* ------------------------- item types ---------------------------- */
|
||||
/* new item types, info1, info2 to be defined during PU development */
|
||||
/* make sure this stays in sync with "is_valid_itemtype" function */
|
||||
#define PICODATA_ITEM_WSEQ_GRAPH '\x73' /* 115, 's' */
|
||||
#define PICODATA_ITEM_TOKEN '\x74' /* 116 't' */
|
||||
#define PICODATA_ITEM_WORDGRAPH '\x67' /* 103 'g' */
|
||||
#define PICODATA_ITEM_WORDINDEX '\x69' /* 105 'i' */
|
||||
#define PICODATA_ITEM_WORDPHON '\x77' /* 119 'w' */
|
||||
#define PICODATA_ITEM_SYLLPHON '\x79' /* 121 'y' */
|
||||
#define PICODATA_ITEM_BOUND '\x62' /* 98 'b' */
|
||||
/* #define PICODATA_ITEM_BOUND_DUR '\x64' */ /* 100 'd' */ /* duration-constrained bound */
|
||||
#define PICODATA_ITEM_PUNC '\x70' /* 112 'p' */
|
||||
#define PICODATA_ITEM_CMD '\x63' /* 99 'c' */
|
||||
#define PICODATA_ITEM_PHONE '\x68' /* 104 'h' */ /*reserved for PAM*/
|
||||
#define PICODATA_ITEM_FRAME_PAR '\x6b' /* 107 'k' */ /*reserved for CEP*/
|
||||
#define PICODATA_ITEM_FRAME '\x66' /* 102 'f' */ /*reserved for SIG*/
|
||||
#define PICODATA_ITEM_OTHER '\x6f' /* 111 'o' */
|
||||
#define PICODATA_ITEM_ERR '\x00' /* 0 '^@' */
|
||||
|
||||
/* generic iteminfo1 */
|
||||
#define PICODATA_ITEMINFO1_ERR '\x00' /* 0 '^@' */ /* error state */
|
||||
#define PICODATA_ITEMINFO1_NA '\x01' /* 1 '^A' */ /* not applicable */
|
||||
|
||||
/* generic iteminfo2 */
|
||||
#define PICODATA_ITEMINFO2_ERR '\x00' /* 0 '^@' */ /* error state */
|
||||
#define PICODATA_ITEMINFO2_NA '\x01' /* 1 '^A' */ /* not applicable */
|
||||
|
||||
/* ------------------------- PUNC item type ---------------------------- */
|
||||
/* iteminfo1 */
|
||||
#define PICODATA_ITEMINFO1_PUNC_SENTEND '\x73' /* 115 's' */
|
||||
#define PICODATA_ITEMINFO1_PUNC_PHRASEEND '\x70' /* 112 'p' */
|
||||
#define PICODATA_ITEMINFO1_PUNC_FLUSH '\x66' /* 102 'f' */
|
||||
/* iteminfo2 */
|
||||
#define PICODATA_ITEMINFO2_PUNC_SENT_T '\x74' /* 116 't' */
|
||||
#define PICODATA_ITEMINFO2_PUNC_SENT_Q '\x71' /* 113 'q' */
|
||||
#define PICODATA_ITEMINFO2_PUNC_SENT_E '\x65' /* 101 'e' */
|
||||
#define PICODATA_ITEMINFO2_PUNC_PHRASE '\x70' /* 112 'p' */
|
||||
#define PICODATA_ITEMINFO2_PUNC_PHRASE_FORCED '\x66' /* 102 'f' */
|
||||
/* len for PUNC item is ALWAYS = 0 */
|
||||
/* ------------------------- BOUND item type ---------------------------- */
|
||||
/* iteminfo1 : phrase strength*/
|
||||
#define PICODATA_ITEMINFO1_BOUND_SBEG '\x62' /* 98 'b', at sentence begin */
|
||||
#define PICODATA_ITEMINFO1_BOUND_SEND '\x73' /* 115 's', at sentence end */
|
||||
#define PICODATA_ITEMINFO1_BOUND_TERM '\x74' /* 116 't', replaces a flush */
|
||||
#define PICODATA_ITEMINFO1_BOUND_PHR0 '\x30' /* 48 '0', no break, no item */
|
||||
#define PICODATA_ITEMINFO1_BOUND_PHR1 '\x31' /* 49 '1', pri. phrase bound. */
|
||||
#define PICODATA_ITEMINFO1_BOUND_PHR2 '\x32' /* 50 '2', short break */
|
||||
#define PICODATA_ITEMINFO1_BOUND_PHR3 '\x33' /* 51 '3', sec. phr. bound., no break*/
|
||||
/* iteminfo2 : phrase type*/
|
||||
#define PICODATA_ITEMINFO2_BOUNDTYPE_P '\x50' /* 80 'P' */
|
||||
#define PICODATA_ITEMINFO2_BOUNDTYPE_T '\x54' /* 84 'T' */
|
||||
#define PICODATA_ITEMINFO2_BOUNDTYPE_Q '\x51' /* 81 'Q' */
|
||||
#define PICODATA_ITEMINFO2_BOUNDTYPE_E '\x45' /* 69 'E' */
|
||||
/* len for BOUND item is ALWAYS = 0 */
|
||||
/* ------------------------- CMD item type ---------------------------- */
|
||||
/* iteminfo1 */
|
||||
#define PICODATA_ITEMINFO1_CMD_FLUSH 'f' /* 102 flush command (all PUs)*/
|
||||
#define PICODATA_ITEMINFO1_CMD_PLAY 'p' /* 112 play command : PU in info 2 will read items from file-->Filename in item content.*/
|
||||
#define PICODATA_ITEMINFO1_CMD_SAVE 's' /* 115 save command : PU in info 2 will save items to file-->Filename in item content.*/
|
||||
#define PICODATA_ITEMINFO1_CMD_UNSAVE 'u' /* 117 save command : PU in info 2 will stop saving items to file*/
|
||||
#define PICODATA_ITEMINFO1_CMD_PROSDOMAIN 'd' /* 100 prosody domain : domain type in info 2, domain name in item content */
|
||||
#define PICODATA_ITEMINFO1_CMD_SPELL 'e' /* 101 spell command : info 2 contains start/stop info,
|
||||
spell type/pause len as little endian uint16 in item content */
|
||||
#define PICODATA_ITEMINFO1_CMD_IGNSIG 'i' /* ignore signal command : info 2 contains start/stop info */
|
||||
#define PICODATA_ITEMINFO1_CMD_PHONEME 'o' /* phoneme command : info 2 contains start/stop info, phonemes in item content */
|
||||
#define PICODATA_ITEMINFO1_CMD_IGNORE 'I' /* ignore text command : info 2 contains start/stop info */
|
||||
#define PICODATA_ITEMINFO1_CMD_SIL 'z' /* silence command : info 2 contains type of silence;
|
||||
silence duration as little endian uint16 in item content */
|
||||
#define PICODATA_ITEMINFO1_CMD_CONTEXT 'c' /* context command : context name in item content */
|
||||
#define PICODATA_ITEMINFO1_CMD_VOICE 'v' /* context command : voice name in item content */
|
||||
#define PICODATA_ITEMINFO1_CMD_MARKER 'm' /* marker command : marker name in item content */
|
||||
#define PICODATA_ITEMINFO1_CMD_PITCH 'P' /* 80 pitch command : abs/rel info in info 2; pitch level as little endian
|
||||
uint16 in item content; relative value is in promille */
|
||||
#define PICODATA_ITEMINFO1_CMD_SPEED 'R' /* 82 speed command : abs/rel info in info 2, speed level as little endian
|
||||
uint16 in item content; elative value is in promille */
|
||||
#define PICODATA_ITEMINFO1_CMD_VOLUME 'V' /* 86 volume command : abs/rel info in info 2, volume level as little endian
|
||||
uint16 in item content; relative value is in promille */
|
||||
#define PICODATA_ITEMINFO1_CMD_SPEAKER 'S' /* 83 speaker command : abs/rel info in info 2, speaker level as little endian
|
||||
uint16 in item content; relative value is in promille */
|
||||
|
||||
/* iteminfo2 for PLAY/SAVE */
|
||||
#define PICODATA_ITEMINFO2_CMD_TO_TOK 't' /* CMD+PLAY/SAVE+TOKENISATION*/
|
||||
#define PICODATA_ITEMINFO2_CMD_TO_PR 'g' /* CMD+PLAY/SAVE+PREPROC*/
|
||||
#define PICODATA_ITEMINFO2_CMD_TO_WA 'w' /* CMD+PLAY/SAVE+WORDANA*/
|
||||
#define PICODATA_ITEMINFO2_CMD_TO_SA 'a' /* CMD+PLAY/SAVE+SENTANA*/
|
||||
#define PICODATA_ITEMINFO2_CMD_TO_ACPH 'h' /* CMD+PLAY/SAVE+ACCENTUATION&PHRASING*/
|
||||
#define PICODATA_ITEMINFO2_CMD_TO_SPHO 'p' /* CMD+PLAY/SAVE+ACCENTUATION&PHRASING*/
|
||||
#define PICODATA_ITEMINFO2_CMD_TO_PAM 'q' /* CMD+PLAY/SAVE+PHONETIC-ACOUSTIC MAPPING*/
|
||||
#define PICODATA_ITEMINFO2_CMD_TO_CEP 'c' /* CMD+PLAY/SAVE+CEP_SMOOTHER*/
|
||||
#define PICODATA_ITEMINFO2_CMD_TO_SIG 's' /* CMD+PLAY/SAVE+SIG_GEN */
|
||||
|
||||
#if 0
|
||||
#define PICODATA_ITEMINFO2_CMD_TO_FST 'f' /* CMD+PLAY/SAVE+FST for Syll and Phonotactic constraints*/
|
||||
#endif
|
||||
|
||||
#define PICODATA_ITEMINFO2_CMD_TO_UNKNOWN 255
|
||||
|
||||
/* iteminfo2 for start/end commands */
|
||||
#define PICODATA_ITEMINFO2_CMD_START 's'
|
||||
#define PICODATA_ITEMINFO2_CMD_END 'e'
|
||||
|
||||
/* iteminfo2 for speed/pitch/volume commands */
|
||||
#define PICODATA_ITEMINFO2_CMD_ABSOLUTE 'a'
|
||||
#define PICODATA_ITEMINFO2_CMD_RELATIVE 'r'
|
||||
|
||||
/* len for CMD item could be >= 0 */
|
||||
/* ------------------------- TOKEN item type ---------------------------- */
|
||||
/* iteminfo1: simple token type : */
|
||||
#define PICODATA_ITEMINFO1_TOKTYPE_SPACE 'W'
|
||||
#define PICODATA_ITEMINFO1_TOKTYPE_LETTERV 'V'
|
||||
#define PICODATA_ITEMINFO1_TOKTYPE_LETTER 'L'
|
||||
#define PICODATA_ITEMINFO1_TOKTYPE_DIGIT 'D'
|
||||
#define PICODATA_ITEMINFO1_TOKTYPE_SEQ 'S'
|
||||
#define PICODATA_ITEMINFO1_TOKTYPE_CHAR 'C'
|
||||
#define PICODATA_ITEMINFO1_TOKTYPE_BEGIN 'B'
|
||||
#define PICODATA_ITEMINFO1_TOKTYPE_END 'E'
|
||||
#define PICODATA_ITEMINFO1_TOKTYPE_UNDEFINED 'U'
|
||||
/* iteminfo2 : token subtype */
|
||||
/* len for WORDTOK item is ALWAYS > 0, if len==0 an error should be raised */
|
||||
|
||||
/**
|
||||
* @addtogroup picodata
|
||||
*
|
||||
* ------------------------- WORDGRAPH item type ----------------------------
|
||||
* - iteminfo1 : POS and multi-POS values defined in lingware
|
||||
* - iteminfo2 : not applicable
|
||||
* - len for WORDGRAPH item is ALWAYS > 0, if len==0 an error should be raised
|
||||
* (currently picopr may produce empty WORDGRAPH that is eliminated by picowa)
|
||||
* \n------------------------- WORDINDEX item type ----------------------------
|
||||
* - iteminfo1 : POS and multi-POS values defined in lingware
|
||||
* - iteminfo2 : not applicable
|
||||
* - len for WORDINDEX item is ALWAYS > 0, if len==0 an error should be raised
|
||||
* \n------------------------- WORDPHON item type ----------------------------
|
||||
* - iteminfo1 : POS values defined in lingware
|
||||
* - iteminfo2 : Uses PICODATA_ACC0 .. ACC4
|
||||
* -len WORDPHON item is ALWAYS > 0, if len==0 an error should be raised
|
||||
* \n------------------------- SYLLPHON item type ----------------------------
|
||||
* - iteminfo1 : not applicable
|
||||
* - iteminfo2 : Uses PICODATA_ACC0 .. ACC4
|
||||
* - len for SYLLPHON item is ALWAYS > 0, if len==0 an error should be raised
|
||||
* \n------------------------- PHONE item type (PRODUCED BY PAM)-----------------
|
||||
* - iteminfo1 : phonId : the phonetic identity of the phone
|
||||
* - iteminfo2 : n_S_P_Phone : number of states per phoneme
|
||||
* - len for PHON item is ALWAYS > 0, if len==0 an error should be raised
|
||||
* \n------------------------- FRAME_PAR item type (PRODUCED BY CEP) --------
|
||||
* - iteminfo1 : format (float, fixed)
|
||||
* - iteminfo2 : vector size
|
||||
* - len for FRAME_PAR item is ALWAYS > 0, if len==0 an error should be raised
|
||||
* \n------------------------- FRAME item type (PRODUCED BY SIG) -----------
|
||||
* - iteminfo1 : number of samples per frame
|
||||
* - iteminfo2 : number of bytes per sample
|
||||
* - len for FRAME item is ALWAYS > 0, if len==0 an error should be raised
|
||||
*
|
||||
*/
|
||||
#define PICODATA_ITEMINFO1_FRAME_PAR_DATA_FORMAT_FIXED '\x78' /* 120 'x' fixed point */
|
||||
#define PICODATA_ITEMINFO1_FRAME_PAR_DATA_FORMAT_FLOAT '\x66' /* 102 'f' floating point */
|
||||
|
||||
/* ***************************************************************
|
||||
* items: CharBuffer functions *
|
||||
*****************************************************************/
|
||||
|
||||
/* gets a single item (head and content) from a CharBuffer in buf;
|
||||
blenmax is the max length (in number of bytes) of buf; blen is
|
||||
set to the number of bytes gotten in buf; return values:
|
||||
PICO_OK <- one item gotten
|
||||
PICO_EOF <- no item available, cb is empty
|
||||
PICO_EXC_BUF_UNDERFLOW <- cb not empty, but no valid item
|
||||
PICO_EXC_BUF_OVERFLOW <- buf not large enough
|
||||
*/
|
||||
pico_status_t picodata_cbGetItem(register picodata_CharBuffer this,
|
||||
picoos_uint8 *buf, const picoos_uint16 blenmax,
|
||||
picoos_uint16 *blen);
|
||||
|
||||
/* gets the speech data (without item head) from a CharBuffer in buf;
|
||||
blenmax is the max length (in number of bytes) of buf; blen is
|
||||
set to the number of bytes gotten in buf; return values:
|
||||
PICO_OK <- speech data of one item gotten
|
||||
PICO_EOF <- no item available, cb is empty
|
||||
PICO_EXC_BUF_UNDERFLOW <- cb not empty, but no valid item
|
||||
PICO_EXC_BUF_OVERFLOW <- buf not large enough
|
||||
*/
|
||||
pico_status_t picodata_cbGetSpeechData(register picodata_CharBuffer this,
|
||||
picoos_uint8 *buf, const picoos_uint16 blenmax,
|
||||
picoos_uint16 *blen);
|
||||
|
||||
/* puts a single item (head and content) to a CharBuffer; clenmax is
|
||||
the max length (in number of bytes) accessible in content; clen is
|
||||
set to the number of bytes put from content; return values:
|
||||
PICO_OK <- one item put
|
||||
PICO_EXC_BUF_UNDERFLOW <- no valid item in buf
|
||||
PICO_EXC_BUF_OVERFLOW <- cb not large enough
|
||||
*/
|
||||
pico_status_t picodata_cbPutItem(register picodata_CharBuffer this,
|
||||
const picoos_uint8 *buf, const picoos_uint16 blenmax,
|
||||
picoos_uint16 *blen);
|
||||
|
||||
/* unsafe, just for measuring purposes */
|
||||
picoos_uint8 picodata_cbGetFrontItemType(register picodata_CharBuffer this);
|
||||
|
||||
/* ***************************************************************
|
||||
* items: support function *
|
||||
*****************************************************************/
|
||||
|
||||
/* checks, whether item of type 'ch' is a valid item type */
|
||||
picoos_uint8 is_valid_itemtype(const picoos_uint8 ch);
|
||||
|
||||
/* gets from buf a single item, values in head set and item content
|
||||
copied to content; blenmax and clenmax are the max lengths (in
|
||||
number of bytes) accessible in buf and content; clen is set to the
|
||||
number of bytes gotten in content; return values:
|
||||
PICO_OK <- all ok
|
||||
PICO_EXC_BUF_UNDERFLOW <- blenmax problem, or no valid item
|
||||
PICO_EXC_BUF_OVERFLOW <- overflow in content
|
||||
*/
|
||||
pico_status_t picodata_get_itemparts_nowarn(
|
||||
const picoos_uint8 *buf, const picoos_uint16 blenmax,
|
||||
picodata_itemhead_t *head, picoos_uint8 *content,
|
||||
const picoos_uint16 clenmax, picoos_uint16 *clen);
|
||||
|
||||
/* gets from buf a single item, values in head set and item content
|
||||
copied to content; blenmax and clenmax are the max lengths (in
|
||||
number of bytes) accessible in buf and content; clen is set to the
|
||||
number of bytes gotten in content; return values:
|
||||
PICO_OK <- all ok
|
||||
PICO_EXC_BUF_UNDERFLOW <- blenmax problem, or no valid item
|
||||
PICO_EXC_BUF_OVERFLOW <- overflow in content
|
||||
*/
|
||||
pico_status_t picodata_get_itemparts(
|
||||
const picoos_uint8 *buf, const picoos_uint16 blenmax,
|
||||
picodata_itemhead_t *head, picoos_uint8 *content,
|
||||
const picoos_uint16 clenmax, picoos_uint16 *clen);
|
||||
|
||||
/* puts a single item to buf; values in head and content copied to
|
||||
buf; clenmax is the max length (in number of bytes) accessible in
|
||||
content; blenmax is the max length (bytes) accessible in buf; blen
|
||||
is set to the number of bytes put to buf; return values:
|
||||
PICO_OK <- all ok
|
||||
PICO_EXC_BUF_UNDERFLOW <- clenmax problem, or no valid item
|
||||
PICO_EXC_BUF_OVERFLOW <- overflow in buf
|
||||
*/
|
||||
pico_status_t picodata_put_itemparts(const picodata_itemhead_t *head,
|
||||
const picoos_uint8 *content, const picoos_uint16 clenmax,
|
||||
picoos_uint8 *buf, const picoos_uint16 blenmax, picoos_uint16 *blen);
|
||||
|
||||
/* gets from buf info of a single item, values in head are set and
|
||||
content is set to the start of content in buf (not copied!);
|
||||
content is set to NULL if the content length is 0; blenmax is the
|
||||
max lengths (in number of bytes) accessible in buf; return values:
|
||||
PICO_OK <- all ok
|
||||
PICO_EXC_BUF_UNDERFLOW <- blenmax problem, or no valid item
|
||||
*/
|
||||
pico_status_t picodata_get_iteminfo(
|
||||
picoos_uint8 *buf, const picoos_uint16 blenmax,
|
||||
picodata_itemhead_t *head, picoos_uint8 **content);
|
||||
|
||||
/* copies the item in inbuf to outbuf after first checking if there is
|
||||
a valid item in inbuf; inlenmax and outlenmax are the max length
|
||||
(in number of byte) accessible in the buffers); in *numb the total
|
||||
number of bytes copied to outbuf (incl. header) is returned; return
|
||||
values:
|
||||
PICO_OK <- item copied
|
||||
PICO_EXC_BUF_OVERFLOW <- overflow in outbuf
|
||||
PICO_ERR_OTHER <- no valid item in inbuf
|
||||
*/
|
||||
pico_status_t picodata_copy_item(const picoos_uint8 *inbuf,
|
||||
const picoos_uint16 inlenmax, picoos_uint8 *outbuf,
|
||||
const picoos_uint16 outlenmax, picoos_uint16 *numb);
|
||||
|
||||
/* sets the info1 field in the header contained in the item in buf;
|
||||
return values:
|
||||
PICO_OK <- all ok
|
||||
PICO_EXC_BUF_UNDERFLOW <- underflow in buf
|
||||
*/
|
||||
pico_status_t picodata_set_iteminfo1(picoos_uint8 *buf,
|
||||
const picoos_uint16 blenmax, const picoos_uint8 info);
|
||||
|
||||
/* sets the info2 field in the header contained in the item in buf;
|
||||
return values:
|
||||
PICO_OK <- all ok
|
||||
PICO_EXC_BUF_UNDERFLOW <- underflow in buf
|
||||
*/
|
||||
pico_status_t picodata_set_iteminfo2(picoos_uint8 *buf,
|
||||
const picoos_uint16 blenmax, const picoos_uint8 info);
|
||||
|
||||
/* sets the len field in the header contained in the item in buf;
|
||||
return values:
|
||||
PICO_OK <- all ok
|
||||
PICO_EXC_BUF_UNDERFLOW <- underflow in buf
|
||||
*/
|
||||
pico_status_t picodata_set_itemlen(picoos_uint8 *buf,
|
||||
const picoos_uint16 blenmax, const picoos_uint8 len);
|
||||
|
||||
/* check item validity and return TRUE if valid; return FALSE if
|
||||
invalid; ilenmax is the max index to be used in item
|
||||
*/
|
||||
picoos_uint8 picodata_is_valid_item(const picoos_uint8 *item,
|
||||
const picoos_uint16 ilenmax);
|
||||
|
||||
/* return TRUE if head is a valid item head, FALSE otherwise */
|
||||
picoos_uint8 picodata_is_valid_itemhead(const picodata_itemhead_t *head);
|
||||
|
||||
|
||||
/* ***************************************************************
|
||||
* ProcessingUnit *
|
||||
*****************************************************************/
|
||||
/* public */
|
||||
|
||||
#define PICODATA_MAX_ITEMSIZE (picoos_uint16) (PICODATA_ITEM_HEADSIZE + 256)
|
||||
|
||||
/* different buffer sizes per processing unit */
|
||||
#define PICODATA_BUFSIZE_DEFAULT (picoos_uint16) PICODATA_MAX_ITEMSIZE
|
||||
#define PICODATA_BUFSIZE_TEXT (picoos_uint16) 1 * PICODATA_BUFSIZE_DEFAULT
|
||||
#define PICODATA_BUFSIZE_TOK (picoos_uint16) 2 * PICODATA_BUFSIZE_DEFAULT
|
||||
#define PICODATA_BUFSIZE_PR (picoos_uint16) 2 * PICODATA_BUFSIZE_DEFAULT
|
||||
#define PICODATA_BUFSIZE_WA (picoos_uint16) 2 * PICODATA_BUFSIZE_DEFAULT
|
||||
#define PICODATA_BUFSIZE_SA (picoos_uint16) 2 * PICODATA_BUFSIZE_DEFAULT
|
||||
#define PICODATA_BUFSIZE_ACPH (picoos_uint16) 2 * PICODATA_BUFSIZE_DEFAULT
|
||||
#define PICODATA_BUFSIZE_SPHO (picoos_uint16) 4 * PICODATA_BUFSIZE_DEFAULT
|
||||
#define PICODATA_BUFSIZE_PAM (picoos_uint16) 4 * PICODATA_BUFSIZE_DEFAULT
|
||||
#define PICODATA_BUFSIZE_CEP (picoos_uint16) 16 * PICODATA_BUFSIZE_DEFAULT
|
||||
#define PICODATA_BUFSIZE_SIG (picoos_uint16) 16 * PICODATA_BUFSIZE_DEFAULT
|
||||
#define PICODATA_BUFSIZE_SINK (picoos_uint16) 1 * PICODATA_BUFSIZE_DEFAULT
|
||||
|
||||
/* different types of processing units */
|
||||
typedef enum picodata_putype {
|
||||
PICODATA_PUTYPE_TEXT, /* text */
|
||||
PICODATA_PUTYPE_TOK, /* tokenizer output */
|
||||
PICODATA_PUTYPE_PR, /* preprocessor output */
|
||||
PICODATA_PUTYPE_WA, /* word analysis */
|
||||
PICODATA_PUTYPE_SA, /* sentence analysis */
|
||||
PICODATA_PUTYPE_ACPH, /* accentuation and phrasing */
|
||||
PICODATA_PUTYPE_SPHO, /* sentence phonology (textana postproc) */
|
||||
PICODATA_PUTYPE_PAM, /* phonetics to acoustics mapper processing unit */
|
||||
PICODATA_PUTYPE_CEP, /* cepstral smoothing processing unit */
|
||||
PICODATA_PUTYPE_SIG, /* signal generation processing unit*/
|
||||
PICODATA_PUTYPE_SINK /* item sink unit*/
|
||||
} picodata_putype_t;
|
||||
|
||||
picoos_uint16 picodata_get_default_buf_size (picodata_putype_t puType);
|
||||
|
||||
/* result values returned from the pu->puStep() methode */
|
||||
typedef enum picodata_step_result {
|
||||
PICODATA_PU_ERROR,
|
||||
/* PICODATA_PU_EMPTY, *//* reserved (no internal data to be processed) */
|
||||
PICODATA_PU_IDLE, /* need more input to process internal data */
|
||||
PICODATA_PU_BUSY, /* processing internal data */
|
||||
PICODATA_PU_ATOMIC, /* same as pu_busy, but wants to get next time slot (while in an "atomar" operation) */
|
||||
PICODATA_PU_OUT_FULL /* can't proceed because output is full. (next time slot to be assigned to pu's output's consumer) */
|
||||
} picodata_step_result_t;
|
||||
|
||||
typedef struct picodata_processing_unit * picodata_ProcessingUnit;
|
||||
|
||||
picodata_ProcessingUnit picodata_newProcessingUnit(
|
||||
picoos_MemoryManager mm,
|
||||
picoos_Common common,
|
||||
picodata_CharBuffer cbIn,
|
||||
picodata_CharBuffer cbOut,
|
||||
picorsrc_Voice voice);
|
||||
|
||||
void picodata_disposeProcessingUnit(
|
||||
picoos_MemoryManager mm,
|
||||
picodata_ProcessingUnit * this);
|
||||
|
||||
picodata_CharBuffer picodata_getCbIn(picodata_ProcessingUnit this);
|
||||
picodata_CharBuffer picodata_getCbOut(picodata_ProcessingUnit this);
|
||||
pico_status_t picodata_setCbIn(picodata_ProcessingUnit this, picodata_CharBuffer cbIn);
|
||||
pico_status_t picodata_setCbOut(picodata_ProcessingUnit this, picodata_CharBuffer cbOut);
|
||||
|
||||
/* protected */
|
||||
typedef pico_status_t (* picodata_puInitializeMethod) (register picodata_ProcessingUnit this, picoos_int32 mode);
|
||||
typedef pico_status_t (* picodata_puTerminateMethod) (register picodata_ProcessingUnit this);
|
||||
typedef picodata_step_result_t (* picodata_puStepMethod) (register picodata_ProcessingUnit this, picoos_int16 mode, picoos_uint16 * numBytesOutput);
|
||||
typedef pico_status_t (* picodata_puSubDeallocateMethod) (register picodata_ProcessingUnit this, picoos_MemoryManager mm);
|
||||
|
||||
typedef struct picodata_processing_unit
|
||||
{
|
||||
/* public */
|
||||
picodata_puInitializeMethod initialize;
|
||||
picodata_puStepMethod step;
|
||||
picodata_puTerminateMethod terminate;
|
||||
picorsrc_Voice voice;
|
||||
|
||||
/* protected */
|
||||
picoos_Common common;
|
||||
picodata_CharBuffer cbIn, cbOut;
|
||||
picodata_puSubDeallocateMethod subDeallocate;
|
||||
void * subObj;
|
||||
|
||||
} picodata_processing_unit_t;
|
||||
|
||||
/* currently, only wav input and output is supported */
|
||||
#define PICODATA_PUTYPE_TEXT_OUTPUT_EXTENSION (picoos_uchar*)".txt"
|
||||
#define PICODATA_PUTYPE_TOK_INPUT_EXTENSION PICODATA_PUTYPE_TEXT_OUTPUT_EXTENSION
|
||||
#define PICODATA_PUTYPE_TOK_OUTPUT_EXTENSION (picoos_uchar*)".tok"
|
||||
#define PICODATA_PUTYPE_PR_INPUT_EXTENSION PICODATA_PUTYPE_TOK_OUTPUT_EXTENSION
|
||||
#define PICODATA_PUTYPE_PR_OUTPUT_EXTENSION (picoos_uchar*)".pr"
|
||||
#define PICODATA_PUTYPE_WA_INPUT_EXTENSION PICODATA_PUTYPE_PR_OUTPUT_EXTENSION
|
||||
#define PICODATA_PUTYPE_WA_OUTPUT_EXTENSION (picoos_uchar*)".wa"
|
||||
#define PICODATA_PUTYPE_SA_INPUT_EXTENSION PICODATA_PUTYPE_WA_OUTPUT_EXTENSION
|
||||
#define PICODATA_PUTYPE_SA_OUTPUT_EXTENSION (picoos_uchar*)".sa"
|
||||
#define PICODATA_PUTYPE_ACPH_INPUT_EXTENSION PICODATA_PUTYPE_SA_OUTPUT_EXTENSION
|
||||
#define PICODATA_PUTYPE_ACPH_OUTPUT_EXTENSION (picoos_uchar*)".acph"
|
||||
#define PICODATA_PUTYPE_SPHO_INPUT_EXTENSION PICODATA_PUTYPE_ACPH_OUTPUT_EXTENSION
|
||||
#define PICODATA_PUTYPE_SPHO_OUTPUT_EXTENSION (picoos_uchar*)".spho"
|
||||
#define PICODATA_PUTYPE_PAM_INPUT_EXTENSION PICODATA_PUTYPE_SPHO_OUTPUT_EXTENSION
|
||||
#define PICODATA_PUTYPE_PAM_OUTPUT_EXTENSION (picoos_uchar*)".pam"
|
||||
#define PICODATA_PUTYPE_CEP_INPUT_EXTENSION PICODATA_PUTYPE_PAM_OUTPUT_EXTENSION
|
||||
#define PICODATA_PUTYPE_CEP_OUTPUT_EXTENSION (picoos_uchar*)".cep"
|
||||
#define PICODATA_PUTYPE_SIG_INPUT_EXTENSION PICODATA_PUTYPE_CEP_OUTPUT_EXTENSION /*PP 11.7.08*/
|
||||
#define PICODATA_PUTYPE_SIG_OUTPUT_EXTENSION (picoos_uchar*)".sig"
|
||||
#define PICODATA_PUTYPE_SINK_INPUT_EXTENSION PICODATA_PUTYPE_SIG_OUTPUT_EXTENSION
|
||||
|
||||
/*wav input is for play wav files in sig */
|
||||
#define PICODATA_PUTYPE_WAV_INPUT_EXTENSION (picoos_uchar*)".wav" /*PP 11.7.08*/
|
||||
|
||||
/*wav output is for saving wav (binary) files in sig*/
|
||||
#define PICODATA_PUTYPE_WAV_OUTPUT_EXTENSION (picoos_uchar*)".wav" /*PP 14.7.08*/
|
||||
|
||||
/* ***************************************************************
|
||||
* auxiliary routines *
|
||||
*****************************************************************/
|
||||
|
||||
picoos_uint8 picodata_getPuTypeFromExtension(picoos_uchar * filename, picoos_bool input);
|
||||
|
||||
#define PICODATA_XSAMPA (picoos_uchar *)"xsampa"
|
||||
#define PICODATA_SAMPA (picoos_uchar *)"sampa"
|
||||
#define PICODATA_SVOXPA (picoos_uchar *)"svoxpa"
|
||||
|
||||
/*----------------------------------------------------------*/
|
||||
/** @brief maps an input phone string to its internal representation
|
||||
*
|
||||
* @param transducer initialized SimpleTransducer
|
||||
* @param xsampa_parser fst converting xsampa char input to xsampa ids
|
||||
* @param svoxpa_parser
|
||||
* @param xsampa2svoxpa_mapper
|
||||
* @param inputPhones input phone string in alphabet 'alphabet'
|
||||
* @param alphabet input alphabet
|
||||
* @retval outputPhoneIds output phone string in internal representation
|
||||
* @param maxOutputPhoneIds
|
||||
* @return PICO_OK=mapping done, PICO_ERR_OTHER:unknown alphabet, unknown phones
|
||||
*/
|
||||
/*---------------------------------------------------------*/
|
||||
pico_status_t picodata_mapPAStrToPAIds(
|
||||
picotrns_SimpleTransducer transducer,
|
||||
picoos_Common common,
|
||||
picokfst_FST xsampa_parser,
|
||||
picokfst_FST svoxpa_parser,
|
||||
picokfst_FST xsampa2svoxpa_mapper,
|
||||
picoos_uchar * inputPhones,
|
||||
picoos_uchar * alphabet,
|
||||
picoos_uint8 * outputPhoneIds,
|
||||
picoos_int32 maxOutputPhoneIds);
|
||||
|
||||
/* number of binary digits after the comma for fixed-point calculation */
|
||||
#define PICODATA_PRECISION 10
|
||||
/* constant 0.5 in PICODATA_PRECISION */
|
||||
#define PICODATA_PREC_HALF 512
|
||||
|
||||
void picodata_transformDurations(
|
||||
picoos_uint8 frame_duration_exp,
|
||||
picoos_int8 array_length,
|
||||
picoos_uint8 * inout,
|
||||
const picoos_uint16 * weight, /* integer weights */
|
||||
picoos_int16 mintarget, /* minimum target duration in ms */
|
||||
picoos_int16 maxtarget, /* maximum target duration in ms */
|
||||
picoos_int16 facttarget, /* factor to be multiplied with original length to get the target
|
||||
the factor is fixed-point with precision PRECISION, i.e.
|
||||
the factor as float would be facttarget / PRECISION_FACT
|
||||
if factor is 0, only min/max are considered */
|
||||
picoos_int16 * dur_rest /* in/out, rest in ms */
|
||||
);
|
||||
|
||||
|
||||
|
||||
/* ***************************************************************
|
||||
* For Debugging only *
|
||||
*****************************************************************/
|
||||
|
||||
#if defined (PICO_DEBUG)
|
||||
|
||||
/* convert (pretty print) item head 'head' and put output in 'str',
|
||||
strsize is the maximum length of 'str' in bytes */
|
||||
picoos_char * picodata_head_to_string(const picodata_itemhead_t *head,
|
||||
picoos_char * str, picoos_uint16 strsize);
|
||||
|
||||
/* put 'pref6ch' (max. 6 char prefix) and a pretty print output of
|
||||
'item' in 'str', strlenmax is the maximum length of 'str' in
|
||||
bytes */
|
||||
void picodata_info_item(const picoknow_KnowledgeBase kb,
|
||||
const picoos_uint8 *pref6ch,
|
||||
const picoos_uint8 *item,
|
||||
const picoos_uint16 itemlenmax,
|
||||
const picoos_char *filterfn);
|
||||
|
||||
|
||||
#define PICODATA_INFO_ITEM(kb, pref, item, itemlenmax) \
|
||||
PICODBG_INFO_CTX(); \
|
||||
picodata_info_item(kb, pref, item, itemlenmax, (picoos_char *)__FILE__)
|
||||
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#define PICODATA_INFO_ITEM(kb, pref, item, itemlenmax)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*PICODATA_H_*/
|
||||
@@ -0,0 +1,438 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picodbg.c
|
||||
*
|
||||
* Provides functions and macros to debug the Pico system and to trace
|
||||
* the execution of its code.
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(PICO_DEBUG)
|
||||
|
||||
/* Two variants of colored console output are implemented:
|
||||
COLOR_MODE_WINDOWS
|
||||
uses the Windows API function SetConsoleTextAttribute
|
||||
COLOR_MODE_ANSI
|
||||
uses ANSI escape codes */
|
||||
#if defined(_WIN32)
|
||||
#define COLOR_MODE_WINDOWS
|
||||
#else
|
||||
#define COLOR_MODE_ANSI
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "picodbg.h"
|
||||
|
||||
|
||||
/* Maximum length of a formatted tracing message */
|
||||
#define MAX_MESSAGE_LEN 999
|
||||
|
||||
/* Maximum length of contextual information */
|
||||
#define MAX_CONTEXT_LEN 499
|
||||
|
||||
/* Maximum length of filename filter */
|
||||
#define MAX_FILTERFN_LEN 16
|
||||
|
||||
/* Delimiter used in debug messages */
|
||||
#define MSG_DELIM "|"
|
||||
|
||||
/* Standard output file for debug messages */
|
||||
#define STDDBG stdout /* or stderr */
|
||||
|
||||
/* Default setup */
|
||||
#define PICODBG_DEFAULT_LEVEL PICODBG_LOG_LEVEL_WARN
|
||||
#define PICODBG_DEFAULT_FILTERFN ""
|
||||
#define PICODBG_DEFAULT_FORMAT \
|
||||
(PICODBG_SHOW_LEVEL | PICODBG_SHOW_SRCNAME | PICODBG_SHOW_FUNCTION)
|
||||
#define PICODBG_DEFAULT_COLOR 1
|
||||
|
||||
|
||||
/* Current log level */
|
||||
static int logLevel = PICODBG_DEFAULT_LEVEL;
|
||||
|
||||
/* Current log filter (filename) */
|
||||
static char logFilterFN[MAX_FILTERFN_LEN + 1];
|
||||
|
||||
/* Current log file or NULL if no log file is set */
|
||||
static FILE *logFile = NULL;
|
||||
|
||||
/* Current output format */
|
||||
static int logFormat = PICODBG_DEFAULT_FORMAT;
|
||||
|
||||
/* Color mode for console output (0 : disable colors, != 0 : enable colors */
|
||||
static int optColor = 0;
|
||||
|
||||
/* Buffer for context information */
|
||||
static char ctxbuf[MAX_CONTEXT_LEN + 1];
|
||||
|
||||
/* Buffer to format tracing messages */
|
||||
static char msgbuf[MAX_MESSAGE_LEN + 1];
|
||||
|
||||
|
||||
/* *** Support for colored text output to console *****/
|
||||
|
||||
|
||||
/* Console text colors */
|
||||
enum color_t {
|
||||
/* order matches Windows color codes */
|
||||
ColorBlack,
|
||||
ColorBlue,
|
||||
ColorGreen,
|
||||
ColorCyan,
|
||||
ColorRed,
|
||||
ColorPurple,
|
||||
ColorBrown,
|
||||
ColorLightGray,
|
||||
ColorDarkGray,
|
||||
ColorLightBlue,
|
||||
ColorLightGreen,
|
||||
ColorLightCyan,
|
||||
ColorLightRed,
|
||||
ColorLightPurple,
|
||||
ColorYellow,
|
||||
ColorWhite
|
||||
};
|
||||
|
||||
|
||||
static enum color_t picodbg_getLevelColor(int level)
|
||||
{
|
||||
switch (level) {
|
||||
case PICODBG_LOG_LEVEL_ERROR: return ColorLightRed;
|
||||
case PICODBG_LOG_LEVEL_WARN : return ColorYellow;
|
||||
case PICODBG_LOG_LEVEL_INFO : return ColorGreen;
|
||||
case PICODBG_LOG_LEVEL_DEBUG: return ColorLightGray;
|
||||
case PICODBG_LOG_LEVEL_TRACE: return ColorDarkGray;
|
||||
}
|
||||
return ColorWhite;
|
||||
}
|
||||
|
||||
|
||||
#if defined(COLOR_MODE_WINDOWS)
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
static int picodbg_setTextAttr(FILE *stream, int attr)
|
||||
{
|
||||
HANDLE hConsole;
|
||||
|
||||
if (stream == stdout) {
|
||||
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
} else if (stream == stderr) {
|
||||
hConsole = GetStdHandle(STD_ERROR_HANDLE);
|
||||
} else {
|
||||
hConsole = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (hConsole != INVALID_HANDLE_VALUE) {
|
||||
/* do nothing if console output is redirected to a file */
|
||||
if (GetFileType(hConsole) == FILE_TYPE_CHAR) {
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
GetConsoleScreenBufferInfo(hConsole, &csbi);
|
||||
SetConsoleTextAttribute(hConsole, (WORD) attr);
|
||||
return (int) csbi.wAttributes;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(COLOR_MODE_ANSI)
|
||||
|
||||
static int picodbg_setTextAttr(FILE *stream, int attr)
|
||||
{
|
||||
const char *c = "";
|
||||
|
||||
if (attr == -1) {
|
||||
c = "0";
|
||||
} else switch (attr) {
|
||||
case ColorBlack: c = "0;30"; break;
|
||||
case ColorRed: c = "0;31"; break;
|
||||
case ColorGreen: c = "0;32"; break;
|
||||
case ColorBrown: c = "0;33"; break;
|
||||
case ColorBlue: c = "0;34"; break;
|
||||
case ColorPurple: c = "0;35"; break;
|
||||
case ColorCyan: c = "0;36"; break;
|
||||
case ColorLightGray: c = "0;37"; break;
|
||||
case ColorDarkGray: c = "1;30"; break;
|
||||
case ColorLightRed: c = "1;31"; break;
|
||||
case ColorLightGreen: c = "1;32"; break;
|
||||
case ColorYellow: c = "1;33"; break;
|
||||
case ColorLightBlue: c = "1;34"; break;
|
||||
case ColorLightPurple: c = "1;35"; break;
|
||||
case ColorLightCyan: c = "1;36"; break;
|
||||
case ColorWhite: c = "1;37"; break;
|
||||
}
|
||||
|
||||
fprintf(stream, "\x1b[%sm", c);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int picodbg_setTextAttr(FILE *stream, int attr)
|
||||
{
|
||||
/* avoid 'unreferenced formal parameter' */
|
||||
(void) stream;
|
||||
(void) attr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* *** Auxiliary routines *****/
|
||||
|
||||
|
||||
static const char *picodbg_fileTitle(const char *file)
|
||||
{
|
||||
const char *name = file, *str = file;
|
||||
|
||||
/* try to extract file name without path in a platform independent
|
||||
way, i.e., skip all chars preceding path separator chars like
|
||||
'/' (Unix, MacOSX), '\' (Windows, DOS), and ':' (MacOS9) */
|
||||
while (*str) {
|
||||
if ((*str == '\\') || (*str == '/') || (*str == ':')) {
|
||||
name = str + 1;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
static void picodbg_logToStream(int level, int donewline,
|
||||
const char *context, const char *msg)
|
||||
{
|
||||
int oldAttr = 0;
|
||||
|
||||
if (optColor) {
|
||||
oldAttr = picodbg_setTextAttr(STDDBG, picodbg_getLevelColor(level));
|
||||
}
|
||||
|
||||
fprintf(STDDBG, "%s%s", context, msg);
|
||||
if (donewline) fprintf(STDDBG, "\n");
|
||||
if (logFile != NULL) {
|
||||
fprintf(logFile, "%s%s", context, msg);
|
||||
if (donewline) fprintf(logFile, "\n");
|
||||
}
|
||||
|
||||
if (optColor) {
|
||||
picodbg_setTextAttr(STDDBG, oldAttr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* *** Exported routines *****/
|
||||
|
||||
|
||||
void picodbg_initialize(int level)
|
||||
{
|
||||
logLevel = level;
|
||||
strcpy(logFilterFN, PICODBG_DEFAULT_FILTERFN);
|
||||
logFile = NULL;
|
||||
logFormat = PICODBG_DEFAULT_FORMAT;
|
||||
optColor = PICODBG_DEFAULT_COLOR;
|
||||
PICODBG_ASSERT_RANGE(level, 0, PICODBG_LOG_LEVEL_TRACE);
|
||||
}
|
||||
|
||||
|
||||
void picodbg_terminate()
|
||||
{
|
||||
if (logFile != NULL) {
|
||||
fclose(logFile);
|
||||
}
|
||||
|
||||
logLevel = 0;
|
||||
logFile = NULL;
|
||||
}
|
||||
|
||||
|
||||
void picodbg_setLogLevel(int level)
|
||||
{
|
||||
PICODBG_ASSERT_RANGE(level, 0, PICODBG_LOG_LEVEL_TRACE);
|
||||
logLevel = level;
|
||||
}
|
||||
|
||||
|
||||
void picodbg_setLogFilterFN(const char *name)
|
||||
{
|
||||
strcpy(logFilterFN, name);
|
||||
}
|
||||
|
||||
|
||||
void picodbg_setLogFile(const char *name)
|
||||
{
|
||||
if (logFile != NULL) {
|
||||
fclose(logFile);
|
||||
}
|
||||
|
||||
if ((name != NULL) && (strlen(name) > 0)) {
|
||||
logFile = fopen(name, "wt");
|
||||
} else {
|
||||
logFile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void picodbg_enableColors(int flag)
|
||||
{
|
||||
optColor = (flag != 0);
|
||||
}
|
||||
|
||||
|
||||
void picodbg_setOutputFormat(unsigned int format)
|
||||
{
|
||||
logFormat = format;
|
||||
}
|
||||
|
||||
|
||||
const char *picodbg_varargs(const char *format, ...)
|
||||
{
|
||||
int len;
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
|
||||
len = vsprintf(msgbuf, format, argptr);
|
||||
PICODBG_ASSERT_RANGE(len, 0, MAX_MESSAGE_LEN);
|
||||
|
||||
return msgbuf;
|
||||
}
|
||||
|
||||
|
||||
void picodbg_log(int level, int donewline, const char *file, int line,
|
||||
const char *func, const char *msg)
|
||||
{
|
||||
char cb[MAX_CONTEXT_LEN + 1];
|
||||
|
||||
PICODBG_ASSERT_RANGE(level, 0, PICODBG_LOG_LEVEL_TRACE);
|
||||
|
||||
if ((level <= logLevel) &&
|
||||
((strlen(logFilterFN) == 0) || !strcmp(logFilterFN, picodbg_fileTitle(file)))) {
|
||||
/* compose output format string */
|
||||
strcpy(ctxbuf, "*** ");
|
||||
if (logFormat & PICODBG_SHOW_LEVEL) {
|
||||
switch (level) {
|
||||
case PICODBG_LOG_LEVEL_ERROR:
|
||||
strcat(ctxbuf, "error" MSG_DELIM);
|
||||
break;
|
||||
case PICODBG_LOG_LEVEL_WARN:
|
||||
strcat(ctxbuf, "warn " MSG_DELIM);
|
||||
break;
|
||||
case PICODBG_LOG_LEVEL_INFO:
|
||||
strcat(ctxbuf, "info " MSG_DELIM);
|
||||
break;
|
||||
case PICODBG_LOG_LEVEL_DEBUG:
|
||||
strcat(ctxbuf, "debug" MSG_DELIM);
|
||||
break;
|
||||
case PICODBG_LOG_LEVEL_TRACE:
|
||||
strcat(ctxbuf, "trace" MSG_DELIM);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (logFormat & PICODBG_SHOW_DATE) {
|
||||
/* nyi */
|
||||
}
|
||||
if (logFormat & PICODBG_SHOW_TIME) {
|
||||
/* nyi */
|
||||
}
|
||||
if (logFormat & PICODBG_SHOW_SRCNAME) {
|
||||
sprintf(cb, "%-10s", picodbg_fileTitle(file));
|
||||
strcat(ctxbuf, cb);
|
||||
if (logFormat & PICODBG_SHOW_SRCLINE) {
|
||||
sprintf(cb, "(%d)", line);
|
||||
strcat(ctxbuf, cb);
|
||||
}
|
||||
strcat(ctxbuf, MSG_DELIM);
|
||||
}
|
||||
if (logFormat & PICODBG_SHOW_FUNCTION) {
|
||||
if (strlen(func) > 0) {
|
||||
sprintf(cb, "%-18s", func);
|
||||
strcat(ctxbuf, cb);
|
||||
strcat(ctxbuf, MSG_DELIM);
|
||||
}
|
||||
}
|
||||
|
||||
picodbg_logToStream(level, donewline, ctxbuf, msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void picodbg_log_msg(int level, const char *file, const char *msg)
|
||||
{
|
||||
PICODBG_ASSERT_RANGE(level, 0, PICODBG_LOG_LEVEL_TRACE);
|
||||
|
||||
if ((level <= logLevel) &&
|
||||
((strlen(logFilterFN) == 0) || !strcmp(logFilterFN, picodbg_fileTitle(file)))) {
|
||||
picodbg_logToStream(level, 0, "", msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void picodbg_assert(const char *file, int line, const char *func, const char *expr)
|
||||
{
|
||||
if (strlen(func) > 0) {
|
||||
fprintf(STDDBG, "assertion failed: %s, file %s, function %s, line %d",
|
||||
expr, picodbg_fileTitle(file), func, line);
|
||||
} else {
|
||||
fprintf(STDDBG, "assertion failed: %s, file %s, line %d",
|
||||
expr, picodbg_fileTitle(file), line);
|
||||
}
|
||||
picodbg_terminate();
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
/* To prevent warning about "translation unit is empty" when
|
||||
diagnostic output is disabled. */
|
||||
static void picodbg_dummy(void) {
|
||||
picodbg_dummy();
|
||||
}
|
||||
|
||||
#endif /* defined(PICO_DEBUG) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* end */
|
||||
@@ -0,0 +1,311 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* @file picodbg.h
|
||||
*
|
||||
* Provides functions and macros to debug the Pico system and to trace
|
||||
* the execution of its code.
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup picodbg
|
||||
* ---------------------------------------------------\n
|
||||
* <b> Pico Debug Support </b>\n
|
||||
* ---------------------------------------------------\n
|
||||
* GENERAL REMARKS
|
||||
* ---------------
|
||||
* This module provides a set of macros to help debug the Pico system.
|
||||
* The usage of macros allows for completely removing debug code from
|
||||
* the binaries delivered to customers. To enable diagnostic output
|
||||
* the preprocessor symbol PICO_DEBUG has to be defined.
|
||||
*
|
||||
* By using global variables (to store the current log level etc.)
|
||||
* this module violates a basic Pico design principle!
|
||||
*
|
||||
* Justification:\n
|
||||
* - going without global data would reduce the functionality
|
||||
* of this module considerably (e.g., log level could not be
|
||||
* changed at runtime etc.)
|
||||
* - at the moment, the only known system interdicting global
|
||||
* variables is Symbian; but even there global variables are
|
||||
* possible by using thread-local storage
|
||||
* - allocating global data on the heap would require to pass
|
||||
* a handle to this memory block to all routines of this
|
||||
* module which in turn implies that _every_ function in the
|
||||
* Pico system would require a pointer to some global data;
|
||||
* obviously, this would be very awkward
|
||||
*
|
||||
* Furthermore, this module uses the non-standardized but handy
|
||||
* __FUNCTION__ macro. It expands to the name of the enclosing
|
||||
* function. For compilers not supporting this macro simply
|
||||
* define __FUNCTION__ as an empty string.
|
||||
*
|
||||
*
|
||||
* INITIALIZATION/TERMINATION\n
|
||||
* --------------------------\n
|
||||
* Before using any debug macros, this module has to be initialized
|
||||
* by calling PICODBG_INITIALIZE(). If the routines are not needed
|
||||
* anymore, PICODBG_TERMINATE() has to be called to terminate the
|
||||
* module (e.g., to close the log file).
|
||||
*
|
||||
*
|
||||
* TRACING\n
|
||||
* -------\n
|
||||
* Each tracing message is associated with a log level which describes
|
||||
* its severity. The following levels are supported:
|
||||
* - Trace - Very detailed log messages, potentially of a high
|
||||
* frequency and volume
|
||||
* - Debug - Less detailed and/or less frequent debugging messages
|
||||
* - Info - Informational messages
|
||||
* - Warn - Warnings which don't appear to the Pico user
|
||||
* - Error - Error messages
|
||||
*
|
||||
* Tracing messages can use the well-known printf format specification.
|
||||
* But because variadic macros (macros with a variable no. arguments)
|
||||
* are not commonly supported by compilers a little trick is used
|
||||
* which requires the format string and its arguments to be enclosed
|
||||
* in double parenthesis:
|
||||
*
|
||||
* - PICODBG_INFO(("hello, world!"));
|
||||
* - PICODBG_TRACE(("argc=%d", argc));
|
||||
* ...
|
||||
*
|
||||
* Each tracing message is expected to be a single line of text. Some
|
||||
* contextual information (e.g., log level, time and date, source file
|
||||
* and line number) and a newline are automatically added. The output
|
||||
* format can be customized by a call to PICODBG_SET_OUTPUT_FORMAT().
|
||||
*
|
||||
* Sample output:
|
||||
* - *** info|2008-04-03|14:51:36|dbgdemo.c(15)|hello world
|
||||
* - *** trace|2008-04-03|14:51:36|dbgdemo.c(16)|argc=2
|
||||
* - ...
|
||||
*
|
||||
* To compose a tracing message line consisting of, e.g. the elements
|
||||
* of an array, on the Info level two additional macros shown in the
|
||||
* following example are provided:
|
||||
*
|
||||
* PICODBG_INFO_CTX();\n
|
||||
* for (i = 0; i < len; i++)\n
|
||||
* ...some calc with arr and i\n
|
||||
* PICODBG_INFO_MSG((" %d", arr[i]));\n
|
||||
* }\n
|
||||
* PICODBG_INFO_MSG(("\n"));\n
|
||||
*
|
||||
* Colored output of tracing messages helps to capture severe problems
|
||||
* quickly. This feature is supported on the Windows platform and on
|
||||
* platforms supporting ANSI escape codes. PICODBG_ENABLE_COLORS() lets
|
||||
* you turn on and off colored output.
|
||||
*
|
||||
*
|
||||
* FILTERING\n
|
||||
* ---------\n
|
||||
* By calling PICODBG_SET_LOG_LEVEL() the log level may be changed at
|
||||
* any time to increase/decrease the amount of debugging output.
|
||||
*
|
||||
* By calling PICODBG_SET_LOG_FILTERFN() the log filter may be changed
|
||||
* at any time to change the source file name being used as filter for
|
||||
* log messages (ie. only tracing info of the specified file will be
|
||||
* logged). To disable the file name based filter set the filter file
|
||||
* name to an empty string.
|
||||
*
|
||||
* Future version of this module might provide further filtering
|
||||
* possibilities (e.g., filtering based on function names * etc.).
|
||||
*
|
||||
*
|
||||
* LOGGING\n
|
||||
* -------\n
|
||||
* By default, tracing messages are output to the console (stderr).
|
||||
* This allows for separating diagnostic output from other console
|
||||
* output to stdout. In addition, tracing messages may be saved to
|
||||
* a file by calling PICODBG_SET_LOG_FILE().
|
||||
* Currently, file output is the only additional output target; but
|
||||
* on embedded systems, more output targets may be required (e.g.,
|
||||
* sending output to a serial port or over the network).
|
||||
*
|
||||
*
|
||||
* ASSERTIONS\n
|
||||
* ----------\n
|
||||
* To support the 'design/programming by contract' paradigm, this
|
||||
* module also provides assertions. PICODBG_ASSERT(expr) evualuates
|
||||
* an expression and, when the result is false, prints a diagnostic
|
||||
* message and aborts the program.
|
||||
*
|
||||
*
|
||||
* FUTURE EXTENSIONS\n
|
||||
* -----------------\n
|
||||
* - advanced tracing functions to dump complex data
|
||||
* - debug memory allocation that can be used to assist in
|
||||
* finding memory problems
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(__PICODBG_H__)
|
||||
#define __PICODBG_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Not all compilers support the __FUNCTION__ macro */
|
||||
#if !defined(__FUNCTION__) && !defined(__GNUC__)
|
||||
#define __FUNCTION__ ""
|
||||
#endif
|
||||
|
||||
|
||||
/* Log levels sorted by severity */
|
||||
#define PICODBG_LOG_LEVEL_ERROR 1
|
||||
#define PICODBG_LOG_LEVEL_WARN 2
|
||||
#define PICODBG_LOG_LEVEL_INFO 3
|
||||
#define PICODBG_LOG_LEVEL_DEBUG 4
|
||||
#define PICODBG_LOG_LEVEL_TRACE 5
|
||||
|
||||
/* Output format flags */
|
||||
#define PICODBG_SHOW_LEVEL 0x0001
|
||||
#define PICODBG_SHOW_DATE 0x0002
|
||||
#define PICODBG_SHOW_TIME 0x0004
|
||||
#define PICODBG_SHOW_SRCNAME 0x0008
|
||||
#define PICODBG_SHOW_SRCLINE 0x0010
|
||||
#define PICODBG_SHOW_SRCALL (PICODBG_SHOW_SRCNAME | PICODBG_SHOW_SRCLINE)
|
||||
#define PICODBG_SHOW_FUNCTION 0x0020
|
||||
#define PICODBG_SHOW_POS (PICODBG_SHOW_SRCALL | PICODBG_SHOW_FUNCTION)
|
||||
|
||||
/* definition of PICO_DEBUG enables debugging code */
|
||||
#if defined(PICO_DEBUG)
|
||||
|
||||
#define PICODBG_INITIALIZE(level) \
|
||||
picodbg_initialize(level)
|
||||
|
||||
#define PICODBG_TERMINATE() \
|
||||
picodbg_terminate()
|
||||
|
||||
#define PICODBG_SET_LOG_LEVEL(level) \
|
||||
picodbg_setLogLevel(level)
|
||||
|
||||
#define PICODBG_SET_LOG_FILTERFN(name) \
|
||||
picodbg_setLogFilterFN(name)
|
||||
|
||||
#define PICODBG_SET_LOG_FILE(name) \
|
||||
picodbg_setLogFile(name)
|
||||
|
||||
#define PICODBG_ENABLE_COLORS(flag) \
|
||||
picodbg_enableColors(flag)
|
||||
|
||||
#define PICODBG_SET_OUTPUT_FORMAT(format) \
|
||||
picodbg_setOutputFormat(format)
|
||||
|
||||
|
||||
#define PICODBG_ASSERT(expr) \
|
||||
for (;!(expr);picodbg_assert(__FILE__, __LINE__, __FUNCTION__, #expr))
|
||||
|
||||
#define PICODBG_ASSERT_RANGE(val, min, max) \
|
||||
PICODBG_ASSERT(((val) >= (min)) && ((val) <= (max)))
|
||||
|
||||
|
||||
#define PICODBG_LOG(level, msg) \
|
||||
picodbg_log(level, 1, __FILE__, __LINE__, __FUNCTION__, picodbg_varargs msg)
|
||||
|
||||
#define PICODBG_ERROR(msg) \
|
||||
PICODBG_LOG(PICODBG_LOG_LEVEL_ERROR, msg)
|
||||
|
||||
#define PICODBG_WARN(msg) \
|
||||
PICODBG_LOG(PICODBG_LOG_LEVEL_WARN, msg)
|
||||
|
||||
#define PICODBG_INFO(msg) \
|
||||
PICODBG_LOG(PICODBG_LOG_LEVEL_INFO, msg)
|
||||
|
||||
#define PICODBG_DEBUG(msg) \
|
||||
PICODBG_LOG(PICODBG_LOG_LEVEL_DEBUG, msg)
|
||||
|
||||
#define PICODBG_TRACE(msg) \
|
||||
PICODBG_LOG(PICODBG_LOG_LEVEL_TRACE, msg)
|
||||
|
||||
|
||||
#define PICODBG_INFO_CTX() \
|
||||
picodbg_log(PICODBG_LOG_LEVEL_INFO, 0, __FILE__, __LINE__, __FUNCTION__, "")
|
||||
|
||||
#define PICODBG_INFO_MSG(msg) \
|
||||
picodbg_log_msg(PICODBG_LOG_LEVEL_INFO, __FILE__, picodbg_varargs msg)
|
||||
|
||||
#define PICODBG_INFO_MSG_F(filterfn, msg) \
|
||||
picodbg_log_msg(PICODBG_LOG_LEVEL_INFO, (const char *)filterfn, picodbg_varargs msg)
|
||||
|
||||
|
||||
|
||||
/* helper routines; should NOT be used directly! */
|
||||
|
||||
void picodbg_initialize(int level);
|
||||
void picodbg_terminate();
|
||||
|
||||
void picodbg_setLogLevel(int level);
|
||||
void picodbg_setLogFilterFN(const char *name);
|
||||
void picodbg_setLogFile(const char *name);
|
||||
void picodbg_enableColors(int flag);
|
||||
void picodbg_setOutputFormat(unsigned int format);
|
||||
|
||||
const char *picodbg_varargs(const char *format, ...);
|
||||
|
||||
void picodbg_log(int level, int donewline, const char *file, int line,
|
||||
const char *func, const char *msg);
|
||||
void picodbg_assert(const char *file, int line, const char *func,
|
||||
const char *expr);
|
||||
|
||||
void picodbg_log_msg(int level, const char *file, const char *msg);
|
||||
|
||||
|
||||
#else /* release version; omit debugging code */
|
||||
|
||||
#define PICODBG_INITIALIZE(level)
|
||||
#define PICODBG_TERMINATE()
|
||||
#define PICODBG_SET_LOG_LEVEL(level)
|
||||
#define PICODBG_SET_LOG_FILTERFN(name)
|
||||
#define PICODBG_SET_LOG_FILE(name)
|
||||
#define PICODBG_ENABLE_COLORS(flag)
|
||||
#define PICODBG_SET_OUTPUT_FORMAT(format)
|
||||
|
||||
#define PICODBG_ASSERT(expr)
|
||||
#define PICODBG_ASSERT_RANGE(val, min, max)
|
||||
|
||||
#define PICODBG_LOG(level, msg)
|
||||
#define PICODBG_ERROR(msg)
|
||||
#define PICODBG_WARN(msg)
|
||||
#define PICODBG_INFO(msg)
|
||||
#define PICODBG_DEBUG(msg)
|
||||
#define PICODBG_TRACE(msg)
|
||||
|
||||
#define PICODBG_INFO_CTX()
|
||||
#define PICODBG_INFO_MSG(msg)
|
||||
#define PICODBG_INFO_MSG_F(filterfn, msg)
|
||||
|
||||
|
||||
#endif /* defined(PICO_DEBUG) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* !defined(__PICODBG_H__) */
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picodefs.h
|
||||
*
|
||||
* SVOX Pico definitions
|
||||
* (SVOX Pico version 1.0 and later)
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PICODEFS_H_
|
||||
#define PICODEFS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* ********************************************************************/
|
||||
/* SVOX Pico limits */
|
||||
/* ********************************************************************/
|
||||
/* maximum size of a voice name, including the terminating null
|
||||
character */
|
||||
#define PICO_MAX_VOICE_NAME_SIZE 32
|
||||
|
||||
/* maximum size of a resource name, incl. the terminating null
|
||||
character */
|
||||
#define PICO_MAX_RESOURCE_NAME_SIZE 32
|
||||
|
||||
/* maximum size of a data path name, incl. the terminating null
|
||||
character */
|
||||
#define PICO_MAX_DATAPATH_NAME_SIZE 128
|
||||
|
||||
/* maximum size of a file name, incl. the terminating null
|
||||
character */
|
||||
#define PICO_MAX_FILE_NAME_SIZE 64
|
||||
|
||||
/* maximum number of resources */
|
||||
#define PICO_MAX_NUM_RESOURCES 64
|
||||
|
||||
/* maximum number of voice definitions */
|
||||
#define PICO_MAX_NUM_VOICE_DEFINITIONS 64
|
||||
|
||||
/* maximum number of resources per voice */
|
||||
#define PICO_MAX_NUM_RSRC_PER_VOICE 16
|
||||
|
||||
/* maximum length of foreign header prepended to PICO resource files
|
||||
(header length must be a multiple of 4 bytes) */
|
||||
#define PICO_MAX_FOREIGN_HEADER_LEN 64
|
||||
|
||||
|
||||
|
||||
/* ********************************************************************/
|
||||
/* SVOX PICO status codes */
|
||||
/* ********************************************************************/
|
||||
|
||||
typedef signed int pico_Status;
|
||||
|
||||
|
||||
/* Okay ***************************************************************/
|
||||
/* functions return PICO_OK if all is okay */
|
||||
|
||||
#define PICO_OK (pico_Status) 0
|
||||
|
||||
|
||||
/* Exceptions and error codes *****************************************/
|
||||
|
||||
/* in case of exceptional events and errors (e.g. unexpected user
|
||||
input) that disrupt the normal flow of operation, PICO_EXC_* or
|
||||
PICO_ERR_* are returned. */
|
||||
|
||||
#define PICO_EXC_NUMBER_FORMAT (pico_Status) -10
|
||||
#define PICO_EXC_MAX_NUM_EXCEED (pico_Status) -11
|
||||
#define PICO_EXC_NAME_CONFLICT (pico_Status) -12
|
||||
#define PICO_EXC_NAME_UNDEFINED (pico_Status) -13
|
||||
#define PICO_EXC_NAME_ILLEGAL (pico_Status) -14
|
||||
|
||||
/* buffer interaction */
|
||||
#define PICO_EXC_BUF_OVERFLOW (pico_Status) -20
|
||||
#define PICO_EXC_BUF_UNDERFLOW (pico_Status) -21
|
||||
#define PICO_EXC_BUF_IGNORE (pico_Status) -22
|
||||
|
||||
/* internal memory handling */
|
||||
#define PICO_EXC_OUT_OF_MEM (pico_Status) -30
|
||||
|
||||
/* files */
|
||||
#define PICO_EXC_CANT_OPEN_FILE (pico_Status) -40
|
||||
#define PICO_EXC_UNEXPECTED_FILE_TYPE (pico_Status) -41
|
||||
#define PICO_EXC_FILE_CORRUPT (pico_Status) -42
|
||||
#define PICO_EXC_FILE_NOT_FOUND (pico_Status) -43
|
||||
|
||||
/* resources */
|
||||
#define PICO_EXC_RESOURCE_BUSY (pico_Status) -50
|
||||
#define PICO_EXC_RESOURCE_MISSING (pico_Status) -51
|
||||
|
||||
/* knowledge bases */
|
||||
#define PICO_EXC_KB_MISSING (pico_Status) -60
|
||||
|
||||
/* runtime exceptions */
|
||||
#define PICO_ERR_NULLPTR_ACCESS (pico_Status) -100
|
||||
#define PICO_ERR_INVALID_HANDLE (pico_Status) -101
|
||||
#define PICO_ERR_INVALID_ARGUMENT (pico_Status) -102
|
||||
#define PICO_ERR_INDEX_OUT_OF_RANGE (pico_Status) -103
|
||||
|
||||
/* other errors ("external" errors, e.g. hardware failure). */
|
||||
#define PICO_ERR_OTHER (pico_Status) -999
|
||||
|
||||
|
||||
/* Warnings ***********************************************************/
|
||||
|
||||
/* general */
|
||||
#define PICO_WARN_INCOMPLETE (pico_Status) 10
|
||||
#define PICO_WARN_FALLBACK (pico_Status) 11
|
||||
#define PICO_WARN_OTHER (pico_Status) 19
|
||||
|
||||
/* resources */
|
||||
#define PICO_WARN_KB_OVERWRITE (pico_Status) 50
|
||||
#define PICO_WARN_RESOURCE_DOUBLE_LOAD (pico_Status) 51
|
||||
|
||||
/* classifiers */
|
||||
#define PICO_WARN_INVECTOR (pico_Status) 60
|
||||
#define PICO_WARN_CLASSIFICATION (pico_Status) 61
|
||||
#define PICO_WARN_OUTVECTOR (pico_Status) 62
|
||||
|
||||
/* processing units */
|
||||
#define PICO_WARN_PU_IRREG_ITEM (pico_Status) 70
|
||||
#define PICO_WARN_PU_DISCARD_BUF (pico_Status) 71
|
||||
|
||||
|
||||
|
||||
/* ********************************************************************/
|
||||
/* Engine getData return values */
|
||||
/* ********************************************************************/
|
||||
|
||||
#define PICO_STEP_IDLE (pico_Status) 200
|
||||
#define PICO_STEP_BUSY (pico_Status) 201
|
||||
|
||||
#define PICO_STEP_ERROR (pico_Status) -200
|
||||
|
||||
/* ********************************************************************/
|
||||
/* resetEngine reset modes */
|
||||
/* ********************************************************************/
|
||||
|
||||
#define PICO_RESET_FULL 0
|
||||
#define PICO_RESET_SOFT 0x10
|
||||
|
||||
|
||||
/* ********************************************************************/
|
||||
/* Engine getData outDataType values */
|
||||
/* ********************************************************************/
|
||||
|
||||
/* 16 bit PCM samples, native endianness of platform */
|
||||
#define PICO_DATA_PCM_16BIT (pico_Int16) 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*PICODEFS_H_*/
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picodsp.h
|
||||
*
|
||||
* Include file for DSP related data types and constants in Pico
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PICODSP_H_
|
||||
#define PICODSP_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------------------CONSTANTS ----------------------*/
|
||||
/*Normalization factors used at the start and at the end of the sig*/
|
||||
#define PICODSP_START_FLOAT_NORM 0.41f
|
||||
#define PICODSP_ENVSPEC_K1 0.5f
|
||||
#define PICODSP_ENVSPEC_K2 2
|
||||
#define PICODSP_GETEXC_K1 1024
|
||||
#define PICODSP_FIXRESP_NORM 4096.0f
|
||||
#define PICODSP_END_FLOAT_NORM 1.5f*16.0f
|
||||
#define PICODSP_FIX_SCALE1 0x4000000
|
||||
#define PICODSP_FIX_SCALE2 0x4000
|
||||
#define PICODSP_SHIFT_FACT1 10
|
||||
#define PICODSP_SHIFT_FACT2 16
|
||||
#define PICODSP_SHIFT_FACT3 12
|
||||
#define PICODSP_SHIFT_FACT4 1
|
||||
#define PICODSP_SHIFT_FACT5 18
|
||||
#define PICODSP_SHIFT_FACT6 9
|
||||
#define PICOSIG_NORM1 9.14f /100.0f /*normalization factor*/
|
||||
#define PICOSIG_MAXAMP (32767)
|
||||
#define PICOSIG_MINAMP (-32768)
|
||||
#define PICODSP_M_PI 3.14159265358979323846
|
||||
#define PICODSP_MAX_EX 32
|
||||
#define PICODSP_WGT_SHIFT (0x20000000)
|
||||
#define PICODSP_N_RAND_TABLE (760)
|
||||
#define PICODSP_COS_TABLE_LEN (512)
|
||||
#define PICODSP_COS_TABLE_LEN2 (1024)
|
||||
#define PICODSP_COS_TABLE_LEN4 (2048)
|
||||
#define PICODSP_PI_SHIFT (4) /* -log2(PICODSP_COS_TABLE_LEN2/0x4000) */
|
||||
|
||||
#define PICODSP_V_CUTOFF_FREQ 4500
|
||||
#define PICODSP_UV_CUTOFF_FREQ 300
|
||||
#define PICODSP_SAMP_FREQ 16000
|
||||
#define PICODSP_FREQ_WARP_FACT 0.42f
|
||||
|
||||
/*----------------------------CEP/PHASE CONSTANTS----------------------------*/
|
||||
#define PICODSP_CEPORDER 25
|
||||
#define PICODSP_PHASEORDER 72
|
||||
#define CEPST_BUFF_SIZE 3
|
||||
#define PHASE_BUFF_SIZE 5
|
||||
/*----------------------------FFT CONSTANTS----------------------------*/
|
||||
#define PICODSP_FFTSIZE (256)
|
||||
|
||||
#define PICODSP_H_FFTSIZE (PICODSP_FFTSIZE/2)
|
||||
|
||||
#define PICODSP_DISPLACE PICODSP_FFTSIZE/4
|
||||
|
||||
#define PICODSP_H_FFTSIZE (PICODSP_FFTSIZE/2)
|
||||
#define PICODSP_HFFTSIZE_P1 (PICODSP_H_FFTSIZE+1)
|
||||
|
||||
#define FAST_DEVICE(aCount, aAction) \
|
||||
{ \
|
||||
int count_ = (aCount); \
|
||||
int times_ = (count_ + 7) >> 3; \
|
||||
switch (count_ & 7){ \
|
||||
case 0: do { aAction; \
|
||||
case 7: aAction; \
|
||||
case 6: aAction; \
|
||||
case 5: aAction; \
|
||||
case 4: aAction; \
|
||||
case 3: aAction; \
|
||||
case 2: aAction; \
|
||||
case 1: aAction; \
|
||||
} while (--times_ > 0); \
|
||||
} \
|
||||
}
|
||||
/*------------------------------------------------------------------------------------------
|
||||
Fast Exp Approximation now remapped to a function in picoos
|
||||
-----------------------------------------------------------------------------------------*/
|
||||
#define EXP(y) picoos_quick_exp(y)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*PICODSP_H_*/
|
||||
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picoextapi.c
|
||||
*
|
||||
* API extension for development use
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
#include "picodefs.h"
|
||||
#include "picoos.h"
|
||||
#include "picoctrl.h"
|
||||
#include "picodbg.h"
|
||||
#include "picoapi.h"
|
||||
#include "picoextapi.h"
|
||||
#include "picoapid.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
/* this is not used anymore. For the picosh banner, set
|
||||
* progv.progVers in picosh.c instead. */
|
||||
#define PICO_VERSION_INFO (picoos_char *)"invalid"
|
||||
|
||||
|
||||
extern pico_Status pico_initialize_priv(
|
||||
void *memory,
|
||||
const pico_Uint32 size,
|
||||
pico_Int16 enableMemProt,
|
||||
pico_System *system);
|
||||
|
||||
|
||||
/* System initialization and termination functions ****************************/
|
||||
|
||||
|
||||
PICO_FUNC picoext_initialize(
|
||||
void *memory,
|
||||
const pico_Uint32 size,
|
||||
pico_Int16 enableMemProt,
|
||||
pico_System *outSystem
|
||||
)
|
||||
{
|
||||
return pico_initialize_priv(memory, size, enableMemProt, outSystem);
|
||||
}
|
||||
|
||||
|
||||
/* System and lingware inspection functions ***********************************/
|
||||
|
||||
/* @todo : not supported yet */
|
||||
PICO_FUNC picoext_getVersionInfo(
|
||||
pico_Retstring outInfo,
|
||||
const pico_Int16 outInfoMaxLen
|
||||
)
|
||||
{
|
||||
if (outInfo == NULL) {
|
||||
return PICO_ERR_NULLPTR_ACCESS;
|
||||
}
|
||||
picoos_strlcpy((picoos_char *) outInfo, PICO_VERSION_INFO, outInfoMaxLen);
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Debugging/testing support functions *****************************************/
|
||||
|
||||
|
||||
PICO_FUNC picoext_setTraceLevel(
|
||||
pico_System system,
|
||||
pico_Int32 level
|
||||
)
|
||||
{
|
||||
if (NULL == system) {
|
||||
return PICO_ERR_NULLPTR_ACCESS;
|
||||
}
|
||||
if (level < 0) {
|
||||
level = 0;
|
||||
}
|
||||
if (level > PICODBG_LOG_LEVEL_TRACE) {
|
||||
level = PICODBG_LOG_LEVEL_TRACE;
|
||||
}
|
||||
PICODBG_SET_LOG_LEVEL(level);
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
PICO_FUNC picoext_setTraceFilterFN(
|
||||
pico_System system,
|
||||
const pico_Char *name
|
||||
)
|
||||
{
|
||||
|
||||
if (NULL == system) {
|
||||
return PICO_ERR_NULLPTR_ACCESS;
|
||||
}
|
||||
name = name; /*PP 13.10.08 : fix warning "var not used in this function"*/
|
||||
PICODBG_SET_LOG_FILTERFN((const char *)name);
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
PICO_FUNC picoext_setLogFile(
|
||||
pico_System system,
|
||||
const pico_Char *name
|
||||
)
|
||||
{
|
||||
if (NULL == system) {
|
||||
return PICO_ERR_NULLPTR_ACCESS;
|
||||
}
|
||||
name = name; /*PP 13.10.08 : fix warning "var not used in this function"*/
|
||||
PICODBG_SET_LOG_FILE((const char *) name);
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Memory usage ***************************************************************/
|
||||
|
||||
|
||||
pico_Status getMemUsage(
|
||||
picoos_Common common,
|
||||
picoos_bool resetIncremental,
|
||||
picoos_int32 *usedBytes,
|
||||
picoos_int32 *incrUsedBytes,
|
||||
picoos_int32 *maxUsedBytes
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
if (common == NULL) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else {
|
||||
picoos_emReset(common->em);
|
||||
picoos_getMemUsage(common->mm, resetIncremental, usedBytes, incrUsedBytes, maxUsedBytes);
|
||||
status = picoos_emGetExceptionCode(common->em);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
PICO_FUNC picoext_getSystemMemUsage(
|
||||
pico_System system,
|
||||
pico_Int16 resetIncremental,
|
||||
pico_Int32 *outUsedBytes,
|
||||
pico_Int32 *outIncrUsedBytes,
|
||||
pico_Int32 *outMaxUsedBytes
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
if (!is_valid_system_handle(system)) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
} else if ((outUsedBytes == NULL) || (outIncrUsedBytes == NULL) || (outMaxUsedBytes == NULL)) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else {
|
||||
picoos_Common common = pico_sysGetCommon(system);
|
||||
status = getMemUsage(common, resetIncremental != 0, outUsedBytes, outIncrUsedBytes, outMaxUsedBytes);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
PICO_FUNC picoext_getEngineMemUsage(
|
||||
pico_Engine engine,
|
||||
pico_Int16 resetIncremental,
|
||||
pico_Int32 *outUsedBytes,
|
||||
pico_Int32 *outIncrUsedBytes,
|
||||
pico_Int32 *outMaxUsedBytes
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
|
||||
if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
|
||||
status = PICO_ERR_INVALID_HANDLE;
|
||||
} else if ((outUsedBytes == NULL) || (outIncrUsedBytes == NULL) || (outMaxUsedBytes == NULL)) {
|
||||
status = PICO_ERR_NULLPTR_ACCESS;
|
||||
} else {
|
||||
picoos_Common common = picoctrl_engGetCommon((picoctrl_Engine) engine);
|
||||
status = getMemUsage(common, resetIncremental != 0, outUsedBytes, outIncrUsedBytes, outMaxUsedBytes);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
PICO_FUNC picoext_getLastScheduledPU(
|
||||
pico_Engine engine
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
status = picoctrl_getLastScheduledPU((picoctrl_Engine) engine);
|
||||
return status;
|
||||
}
|
||||
|
||||
PICO_FUNC picoext_getLastProducedItemType(
|
||||
pico_Engine engine
|
||||
)
|
||||
{
|
||||
pico_Status status = PICO_OK;
|
||||
status = picoctrl_getLastProducedItemType((picoctrl_Engine) engine);
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* end */
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picoextapi.h
|
||||
*
|
||||
* API extensions for development use
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PICOEXTAPI_H_
|
||||
#define PICOEXTAPI_H_
|
||||
|
||||
#include "picodefs.h"
|
||||
#include "picodbg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ****************************************************************************/
|
||||
/* Things that might be added to picoapi later but should not appear there */
|
||||
/* for the time being */
|
||||
/* ****************************************************************************/
|
||||
|
||||
/* String type for Unicode text input *****************************************/
|
||||
|
||||
/* Unicode encodings supported by PICO. */
|
||||
|
||||
#define PICO_STRENC_UTF8 0
|
||||
#define PICO_STRENC_UTF16 1
|
||||
|
||||
/* An UTF-8 string must point to a byte array, terminated by a null character
|
||||
('\0'). An UTF-16 string must point to a contiguous array of 16-bit units
|
||||
(in native byte ordering), terminated by a 0. */
|
||||
|
||||
typedef char *PICO_STRING_UTF8;
|
||||
typedef pico_Uint16 *PICO_STRING_UTF16;
|
||||
|
||||
/* Generic pointer to a Unicode string, encoded either as UTF-8 or UTF-16.
|
||||
The application must make sure that for each 'PICO_STRING_PTR' it provides
|
||||
an argument of type 'PICO_STRING_UTF8' or 'PICO_STRING_UTF16' (or of a type
|
||||
compatible to one of these types). */
|
||||
|
||||
typedef void *PICO_STRING_PTR;
|
||||
|
||||
|
||||
/* ****************************************************************************/
|
||||
/* System-level API functions */
|
||||
/* ****************************************************************************/
|
||||
|
||||
/* System initialization and termination functions ****************************/
|
||||
|
||||
/* Same as pico_initialize, but allows to enable memory protection
|
||||
functionality for testing purposes (enableMemProt != 0). */
|
||||
|
||||
PICO_FUNC picoext_initialize(
|
||||
void *memory,
|
||||
const pico_Uint32 size,
|
||||
pico_Int16 enableMemProt,
|
||||
pico_System *outSystem
|
||||
);
|
||||
|
||||
|
||||
/* System and lingware inspection functions ***********************************/
|
||||
|
||||
/* Returns version information of the current Pico engine. */
|
||||
|
||||
PICO_FUNC picoext_getVersionInfo(
|
||||
pico_Retstring outInfo,
|
||||
const pico_Int16 outInfoMaxLen
|
||||
);
|
||||
|
||||
/* Returns unique resource name */
|
||||
|
||||
/*
|
||||
PICO_FUNC picoext_getResourceName(
|
||||
pico_Resource resource,
|
||||
pico_Retstring outInfo
|
||||
);
|
||||
*/
|
||||
|
||||
/* Debugging/testing support functions *****************************************/
|
||||
|
||||
/* Sets tracing level. Increasing amounts of information is displayed
|
||||
at each level. */
|
||||
|
||||
PICO_FUNC picoext_setTraceLevel(
|
||||
pico_System system,
|
||||
pico_Int32 level
|
||||
);
|
||||
|
||||
/* Sets trace filtering. Limits tracing output to tracing information
|
||||
resulting from the source file name being filtered. */
|
||||
|
||||
PICO_FUNC picoext_setTraceFilterFN(
|
||||
pico_System system,
|
||||
const pico_Char *name
|
||||
);
|
||||
|
||||
/* Enables logging of debug output to log file 'name'. If 'name' is NULL
|
||||
or an empty string, logging is disabled. */
|
||||
|
||||
PICO_FUNC picoext_setLogFile(
|
||||
pico_System system,
|
||||
const pico_Char *name
|
||||
);
|
||||
|
||||
|
||||
/* Memory usage ***************************************************************/
|
||||
|
||||
PICO_FUNC picoext_getSystemMemUsage(
|
||||
pico_System system,
|
||||
pico_Int16 resetIncremental,
|
||||
pico_Int32 *outUsedBytes,
|
||||
pico_Int32 *outIncrUsedBytes,
|
||||
pico_Int32 *outMaxUsedBytes
|
||||
);
|
||||
|
||||
PICO_FUNC picoext_getEngineMemUsage(
|
||||
pico_Engine engine,
|
||||
pico_Int16 resetIncremental,
|
||||
pico_Int32 *outUsedBytes,
|
||||
pico_Int32 *outIncrUsedBytes,
|
||||
pico_Int32 *outMaxUsedBytes
|
||||
);
|
||||
|
||||
PICO_FUNC picoext_getLastScheduledPU(
|
||||
pico_Engine engine
|
||||
);
|
||||
|
||||
PICO_FUNC picoext_getLastProducedItemType(
|
||||
pico_Engine engine
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* PICOEXTAPI_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picofftsg.h
|
||||
*
|
||||
* include file for FFT/DCT related data types, constants and functions in Pico
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
#ifndef PICOFFTSG_H_
|
||||
#define PICOFFTSG_H_
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picodsp.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
#define PICOFFTSG_FFTTYPE picoos_int32
|
||||
|
||||
extern void rdft(int n, int isgn, PICOFFTSG_FFTTYPE *a);
|
||||
extern void dfct(int n, float *a, int VAL_SHIFT);
|
||||
extern void dfct_nmf(int n, int *a);
|
||||
extern float norm_result(int m2, PICOFFTSG_FFTTYPE *tmpX, PICOFFTSG_FFTTYPE *norm_window);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picokdbg.c
|
||||
*
|
||||
* debug support knowledge base
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picoknow.h"
|
||||
#include "picodbg.h"
|
||||
#include "picokdbg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PICO_DEBUG)
|
||||
|
||||
/**
|
||||
* @addtogroup picokdbg
|
||||
|
||||
* <b> Pico Debug Support for knowledge base </b>\n
|
||||
*
|
||||
|
||||
* @b Phones
|
||||
|
||||
* overview of binary file format for dbg kb:
|
||||
|
||||
dbg-kb = phonesyms
|
||||
|
||||
phonesyms = {PHONESYM8}=256
|
||||
|
||||
PHONESYM6: 8 bytes, symbol name (must be 0 terminated), the
|
||||
corresponding ID corresponds to the offset in the
|
||||
phonesyms array
|
||||
*/
|
||||
|
||||
/* maximum length of phonesym string including terminating 0 */
|
||||
#define KDBG_PHONESYMLEN_MAX 8
|
||||
|
||||
|
||||
typedef struct kdbg_subobj *kdbg_SubObj;
|
||||
|
||||
typedef struct kdbg_subobj {
|
||||
picoos_uint8 *phonesyms;
|
||||
} kdbg_subobj_t;
|
||||
|
||||
|
||||
static pico_status_t kdbgInitialize(register picoknow_KnowledgeBase this,
|
||||
picoos_Common common) {
|
||||
kdbg_subobj_t *kdbg;
|
||||
|
||||
PICODBG_DEBUG(("start"));
|
||||
|
||||
if (NULL == this || NULL == this->subObj) {
|
||||
PICODBG_DEBUG(("2nd check failed"));
|
||||
return picoos_emRaiseException(common->em, PICO_ERR_OTHER, NULL, NULL);
|
||||
}
|
||||
kdbg = (kdbg_subobj_t *)this->subObj;
|
||||
kdbg->phonesyms = this->base;
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
static pico_status_t kdbgSubObjDeallocate(register picoknow_KnowledgeBase this,
|
||||
picoos_MemoryManager mm) {
|
||||
if (NULL != this) {
|
||||
picoos_deallocate(mm, (void *) &this->subObj);
|
||||
}
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
pico_status_t picokdbg_specializeDbgKnowledgeBase(picoknow_KnowledgeBase this,
|
||||
picoos_Common common) {
|
||||
if (NULL == this) {
|
||||
PICODBG_INFO(("no debug symbols loaded"));
|
||||
return PICO_OK;
|
||||
}
|
||||
this->subDeallocate = kdbgSubObjDeallocate;
|
||||
this->subObj = picoos_allocate(common->mm, sizeof(kdbg_subobj_t));
|
||||
if (NULL == this->subObj) {
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_OUT_OF_MEM,
|
||||
NULL, NULL);
|
||||
}
|
||||
return kdbgInitialize(this, common);
|
||||
}
|
||||
|
||||
|
||||
picokdbg_Dbg picokdbg_getDbg(picoknow_KnowledgeBase this) {
|
||||
if (NULL == this) {
|
||||
return NULL;
|
||||
} else {
|
||||
return (picokdbg_Dbg)this->subObj;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Dbg methods */
|
||||
|
||||
picoos_uint8 picokdbg_getPhoneId(const picokdbg_Dbg this,
|
||||
const picoos_char *phsym) {
|
||||
kdbg_subobj_t *kdbg;
|
||||
picoos_uint16 i;
|
||||
|
||||
if (this == NULL)
|
||||
return 0;
|
||||
|
||||
kdbg = (kdbg_subobj_t *)this;
|
||||
/* sequential search */
|
||||
for (i = 0; i < 256; i++) {
|
||||
if (!picoos_strcmp(phsym,
|
||||
(picoos_char *)&(kdbg->phonesyms[i * KDBG_PHONESYMLEN_MAX])))
|
||||
return (picoos_uint8)i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
picoos_char *picokdbg_getPhoneSym(const picokdbg_Dbg this,
|
||||
const picoos_uint8 phid) {
|
||||
kdbg_subobj_t *kdbg;
|
||||
|
||||
if (this == NULL)
|
||||
return NULL;
|
||||
|
||||
kdbg = (kdbg_subobj_t *)this;
|
||||
return (picoos_char *)&(kdbg->phonesyms[phid * KDBG_PHONESYMLEN_MAX]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#else
|
||||
|
||||
/* To prevent warning about "translation unit is empty" when
|
||||
diagnostic output is disabled. */
|
||||
static void picokdbg_dummy(void) {
|
||||
picokdbg_dummy();
|
||||
}
|
||||
|
||||
|
||||
#endif /* defined(PICO_DEBUG) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* end */
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picokdbg.h
|
||||
*
|
||||
* debug support knowledge base
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*- 0.1, 08.05.2008, MRi - initial version
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PICOKDBG_H_
|
||||
#define PICOKDBG_H_
|
||||
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picoknow.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* Dbg type and functions */
|
||||
/* ************************************************************/
|
||||
|
||||
/**
|
||||
* to be used by picorsrc only
|
||||
*/
|
||||
pico_status_t picokdbg_specializeDbgKnowledgeBase(picoknow_KnowledgeBase this,
|
||||
picoos_Common common);
|
||||
|
||||
typedef struct picokdbg_dbg *picokdbg_Dbg;
|
||||
|
||||
/**
|
||||
* return kb Phones for usage in PU
|
||||
*/
|
||||
picokdbg_Dbg picokdbg_getDbg(picoknow_KnowledgeBase this);
|
||||
|
||||
|
||||
/* phone ID - phone symbol conversion functions */
|
||||
|
||||
/**
|
||||
* return phone ID for phone symbol 'phsym' which must be 0 terminated
|
||||
*/
|
||||
picoos_uint8 picokdbg_getPhoneId(const picokdbg_Dbg dbg,
|
||||
const picoos_char *phsym);
|
||||
|
||||
/**
|
||||
* return pointer to phone symbol for phone ID phid
|
||||
*/
|
||||
picoos_char *picokdbg_getPhoneSym(const picokdbg_Dbg dbg,
|
||||
const picoos_uint8 phid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*PICOKDBG_H_*/
|
||||
+2642
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,465 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picokdt.h
|
||||
*
|
||||
* knowledge handling for decision trees
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PICOKDT_H_
|
||||
#define PICOKDT_H_
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picoknow.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/*
|
||||
Several specialized decision trees kb are provided by this
|
||||
knowledge handling module:
|
||||
|
||||
- Part of speech prediction decision tree: ...kdt_PosP
|
||||
- Part of speech disambiguation decision tree: ...kdt_PosD
|
||||
- Grapheme-to-phoneme decision tree: ...kdt_G2P
|
||||
- Phrasing decision tree: ...kdt_PHR
|
||||
- Accentuation decision tree: ...kdt_ACC
|
||||
these 5 tree types may be unified in the future to a single type
|
||||
|
||||
- Phono-acoustical model trees: ...kdt_PAM
|
||||
(actually 11 trees, but all have the same characteristics and
|
||||
are instances of the same class)
|
||||
*/
|
||||
/* ************************************************************/
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* defines and functions to create specialized kb, */
|
||||
/* to be used by picorsrc only */
|
||||
/* ************************************************************/
|
||||
|
||||
typedef enum {
|
||||
PICOKDT_KDTTYPE_POSP,
|
||||
PICOKDT_KDTTYPE_POSD,
|
||||
PICOKDT_KDTTYPE_G2P,
|
||||
PICOKDT_KDTTYPE_PHR,
|
||||
PICOKDT_KDTTYPE_ACC,
|
||||
PICOKDT_KDTTYPE_PAM
|
||||
} picokdt_kdttype_t;
|
||||
|
||||
pico_status_t picokdt_specializeDtKnowledgeBase(picoknow_KnowledgeBase this,
|
||||
picoos_Common common,
|
||||
const picokdt_kdttype_t type);
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* decision tree types (opaque) and get Tree functions */
|
||||
/* ************************************************************/
|
||||
|
||||
/* decision tree types */
|
||||
typedef struct picokdt_dtposp * picokdt_DtPosP;
|
||||
typedef struct picokdt_dtposd * picokdt_DtPosD;
|
||||
typedef struct picokdt_dtg2p * picokdt_DtG2P;
|
||||
typedef struct picokdt_dtphr * picokdt_DtPHR;
|
||||
typedef struct picokdt_dtacc * picokdt_DtACC;
|
||||
typedef struct picokdt_dtpam * picokdt_DtPAM;
|
||||
|
||||
/* return kb decision tree for usage in PU */
|
||||
picokdt_DtPosP picokdt_getDtPosP(picoknow_KnowledgeBase this);
|
||||
picokdt_DtPosD picokdt_getDtPosD(picoknow_KnowledgeBase this);
|
||||
picokdt_DtG2P picokdt_getDtG2P (picoknow_KnowledgeBase this);
|
||||
picokdt_DtPHR picokdt_getDtPHR (picoknow_KnowledgeBase this);
|
||||
picokdt_DtACC picokdt_getDtACC (picoknow_KnowledgeBase this);
|
||||
picokdt_DtPAM picokdt_getDtPAM (picoknow_KnowledgeBase this);
|
||||
|
||||
|
||||
/* number of attributes (= input vector size) for each tree type */
|
||||
typedef enum {
|
||||
PICOKDT_NRATT_POSP = 12,
|
||||
PICOKDT_NRATT_POSD = 7,
|
||||
PICOKDT_NRATT_G2P = 16,
|
||||
PICOKDT_NRATT_PHR = 8,
|
||||
PICOKDT_NRATT_ACC = 13,
|
||||
PICOKDT_NRATT_PAM = 60
|
||||
} kdt_nratt_t;
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* decision tree classification result type */
|
||||
/* ************************************************************/
|
||||
|
||||
typedef struct {
|
||||
picoos_uint8 set; /* TRUE if class set, FALSE otherwise */
|
||||
picoos_uint16 class;
|
||||
} picokdt_classify_result_t;
|
||||
|
||||
|
||||
/* maximum number of output values the tree output is mapped to */
|
||||
#define PICOKDT_MAXSIZE_OUTVEC 8
|
||||
|
||||
typedef struct {
|
||||
picoos_uint8 nr; /* 0 if no class set, nr of values set otherwise */
|
||||
picoos_uint16 classvec[PICOKDT_MAXSIZE_OUTVEC];
|
||||
} picokdt_classify_vecresult_t;
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* decision tree functions */
|
||||
/* ************************************************************/
|
||||
|
||||
/* constructInVec:
|
||||
for every tree type there is a constructInVec function to construct
|
||||
the size-optimized input vector for the tree using the input map
|
||||
tables that are part of the decistion tree knowledge base. The
|
||||
constructed input vector is stored in the tree object (this->invec
|
||||
and this->inveclen) and will be used in the following call to the
|
||||
classify function.
|
||||
|
||||
classify:
|
||||
for every tree type there is a classify function to apply the
|
||||
decision tree to the previously constructed input vector. The
|
||||
size-optimized, encoded output is stored in the tree object
|
||||
(this->outval) and will be used in the following call to the
|
||||
decompose function. Where needed (hitory attribute) the direct tree
|
||||
output is returned by the classify function in a variable.
|
||||
|
||||
decomposeOutClass:
|
||||
for every tree type there is a decompose function to decompose the
|
||||
size-optimized, encoded tree output and map it to the outside the
|
||||
tree usable class value.
|
||||
*/
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* decision tree defines */
|
||||
/* ************************************************************/
|
||||
|
||||
/* to construct the input vectors several hard-coded values are used
|
||||
to handle attributes that, at the given position, are outside the
|
||||
context. */
|
||||
|
||||
/* graph attributes: values to be used if the graph attribute is
|
||||
outside the grapheme string (ie. word) */
|
||||
#define PICOKDT_OUTSIDEGRAPH_DEFCH (picoos_uint8)'\x30' /* ascii "0" */
|
||||
#define PICOKDT_OUTSIDEGRAPH_DEFSTR (picoos_uint8 *)"\x30" /* ascii "0" */
|
||||
#define PICOKDT_OUTSIDEGRAPH_DEFLEN 1
|
||||
|
||||
/* graph attributes (special case for g2p): values to be used if the
|
||||
graph attribute is directly outside the grapheme string (ie. at the
|
||||
word boundary word). Use PICOKDT_OUTSIDEGRAPH_DEF* if further
|
||||
outside. */
|
||||
#define PICOKDT_OUTSIDEGRAPH_EOW_DEFCH (picoos_uint8)'\x31' /* ascii "1" */
|
||||
#define PICOKDT_OUTSIDEGRAPH_EOW_DEFSTR (picoos_uint8 *)"\x31" /* ascii "1" */
|
||||
#define PICOKDT_OUTSIDEGRAPH_EOW_DEFLEN 1
|
||||
|
||||
/* byte and word type attributes: value to be used if a byte or word
|
||||
attribute is outside the context, e.g. for POS */
|
||||
#define PICOKDT_EPSILON 7
|
||||
|
||||
/* byte and word type attributes: for attribute with history info a
|
||||
'zero' value is needed when starting the sequence of predictions.
|
||||
Use the following value to initialize history. Note that the direct
|
||||
tree outputs (not mapped with output map table) of previous
|
||||
predictions need to be used when constructing the input vector for
|
||||
a following prediction. This direct tree output will then be mapped
|
||||
together with the rest of the input vector by the input map
|
||||
table. */
|
||||
#define PICOKDT_HISTORY_ZERO 30000
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* decision tree POS prediction (PosP) functions */
|
||||
/* ************************************************************/
|
||||
|
||||
/* construct a POS prediction input vector
|
||||
tree input vector: 0-3 prefix UTF8 graphemes
|
||||
4-9 suffex UTF8 graphemes
|
||||
10 special grapheme existence flag (TRUE/FALSE)
|
||||
11 number of graphemes
|
||||
graph: the grapheme string of the word for wich POS will be predicted
|
||||
graphlen: length of graph in number of bytes
|
||||
specgraphflag: existence of a special grapheme boolean
|
||||
returns: TRUE if okay, FALSE otherwise
|
||||
note: use PICOKDT_OUTSIDEGRAPH* for att values outside context
|
||||
*/
|
||||
picoos_uint8 picokdt_dtPosPconstructInVec(const picokdt_DtPosP this,
|
||||
const picoos_uint8 *graph,
|
||||
const picoos_uint16 graphlen,
|
||||
const picoos_uint8 specgraphflag);
|
||||
|
||||
|
||||
/* classify a previously constructed input vector using tree 'this'
|
||||
returns: TRUE if okay, FALSE otherwise
|
||||
*/
|
||||
picoos_uint8 picokdt_dtPosPclassify(const picokdt_DtPosP this);
|
||||
|
||||
/* decompose the tree output and return the class in dtres
|
||||
dtres: POS or POSgroup ID classification result
|
||||
returns: TRUE if okay, FALSE otherwise
|
||||
*/
|
||||
picoos_uint8 picokdt_dtPosPdecomposeOutClass(const picokdt_DtPosP this,
|
||||
picokdt_classify_result_t *dtres);
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* decision tree POS disambiguation (PosD) functions */
|
||||
/* ************************************************************/
|
||||
|
||||
/* construct a POS disambiguation input vector (run in left-to-right mode)
|
||||
tree input vector: 0-2 POS or POSgroup for each of the three previous words
|
||||
3 POSgroup for current word
|
||||
4-6 POS or POSgroup (can be history) for each of
|
||||
the three following words
|
||||
pre3 - pre1: POSgroup or POS for the previous three words
|
||||
src: POSgroup of current word (if unique POS no posdisa possible)
|
||||
fol1 - fol3: POS or history for the following three words (the more
|
||||
complicated the better... :-( NEEDS TO BE uint16
|
||||
ishist1-ishist3: flag to indicate if fol1-3 are predicted tree
|
||||
output values (history) or the HISTORY_ZERO (TRUE)
|
||||
or an already unambiguous POS (FALSE)
|
||||
returns: TRUE if okay, FALSE otherwise
|
||||
note: use PICOKDT_EPSILON for att values outside context,
|
||||
if POS in fol* unique use this POS instead of real
|
||||
history, use reverse output mapping in these cases
|
||||
*/
|
||||
picoos_uint8 picokdt_dtPosDconstructInVec(const picokdt_DtPosD this,
|
||||
const picoos_uint16 * input);
|
||||
|
||||
|
||||
/* classify a previously constructed input vector using tree 'this'
|
||||
treeout: direct tree output value
|
||||
returns: TRUE if okay, FALSE otherwise
|
||||
*/
|
||||
picoos_uint8 picokdt_dtPosDclassify(const picokdt_DtPosD this,
|
||||
picoos_uint16 *treeout);
|
||||
|
||||
/* decompose the tree output and return the class in dtres
|
||||
dtres: POS classification result
|
||||
returns: TRUE if okay, FALSE otherwise
|
||||
*/
|
||||
picoos_uint8 picokdt_dtPosDdecomposeOutClass(const picokdt_DtPosD this,
|
||||
picokdt_classify_result_t *dtres);
|
||||
|
||||
/* convert (unique) POS index into corresponding tree output index */
|
||||
picoos_uint8 picokdt_dtPosDreverseMapOutFixed(const picokdt_DtPosD this,
|
||||
const picoos_uint16 inval,
|
||||
picoos_uint16 *outval,
|
||||
picoos_uint16 *outfallbackval);
|
||||
|
||||
/* ************************************************************/
|
||||
/* decision tree grapheme-to-phoneme (G2P) functions */
|
||||
/* ************************************************************/
|
||||
|
||||
/* construct a G2P input vector (run in right-to-left mode)
|
||||
tree input vector: 0-8 the 4 previous, current, and 4 following graphemes
|
||||
9 POS
|
||||
10-11 vowel count and vowel ID
|
||||
12 primary stress flag (TRUE/FALSE)
|
||||
13-15 the three following phones predicted
|
||||
graph: the grapheme string used to determine invec[0:8]
|
||||
graphlen: length of graph in number of bytes
|
||||
count: the grapheme number for which invec will be constructed [0..]
|
||||
pos: the part of speech of the word
|
||||
nrvow number of vowel-like graphemes in graph if vowel,
|
||||
set to 0 otherwise
|
||||
ordvow order of 'count' vowel in graph if vowel,
|
||||
set to 0 otherwise
|
||||
primstressflag: flag indicating if primary stress was already predicted
|
||||
phonech1-3: the three following phon chunks predicted (right-to-left)
|
||||
returns: TRUE if okay, FALSE otherwise
|
||||
*/
|
||||
picoos_uint8 picokdt_dtG2PconstructInVec(const picokdt_DtG2P this,
|
||||
const picoos_uint8 *graph,
|
||||
const picoos_uint16 graphlen,
|
||||
const picoos_uint8 count,
|
||||
const picoos_uint8 pos,
|
||||
const picoos_uint8 nrvow,
|
||||
const picoos_uint8 ordvow,
|
||||
picoos_uint8 *primstressflag,
|
||||
const picoos_uint16 phonech1,
|
||||
const picoos_uint16 phonech2,
|
||||
const picoos_uint16 phonech3);
|
||||
|
||||
/* classify a previously constructed input vector using tree 'this'
|
||||
treeout: direct tree output value
|
||||
returns: TRUE if okay, FALSE otherwise
|
||||
*/
|
||||
picoos_uint8 picokdt_dtG2Pclassify(const picokdt_DtG2P this,
|
||||
picoos_uint16 *treeout);
|
||||
|
||||
/* decompose the tree output and return the class vector in dtvres
|
||||
dtvres: phones vector classification result
|
||||
returns: TRUE if okay, FALSE otherwise
|
||||
*/
|
||||
picoos_uint8 picokdt_dtG2PdecomposeOutClass(const picokdt_DtG2P this,
|
||||
picokdt_classify_vecresult_t *dtvres);
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* decision tree phrasing (PHR) functions */
|
||||
/* ************************************************************/
|
||||
|
||||
/* construct a PHR input vector (run in right-to-left mode)
|
||||
tree input vector: 0-1 POS for each of the two previous words
|
||||
2 POS for current word
|
||||
3-4 POS for each of the two following words
|
||||
5 nr words left
|
||||
6 nr words right
|
||||
7 nr syllables right
|
||||
pre2 - pre1: POS for the previous two words
|
||||
src: POS of current word
|
||||
fol1 - fol2: POS for the following two words
|
||||
nrwordspre: number of words left (previous) of current word
|
||||
nrwordsfol: number of words right (following) of current word,
|
||||
incl. current word, up to next BOUND (also
|
||||
considering previously predicted PHR2/3)
|
||||
nrsyllsfol: number of syllables right (following) of current word,
|
||||
incl. syllables of current word, up to next BOUND
|
||||
(also considering previously predicted PHR2/3)
|
||||
returns: TRUE if okay, FALSE otherwise
|
||||
note: use PICOKDT_EPSILON for att values outside context
|
||||
*/
|
||||
picoos_uint8 picokdt_dtPHRconstructInVec(const picokdt_DtPHR this,
|
||||
const picoos_uint8 pre2,
|
||||
const picoos_uint8 pre1,
|
||||
const picoos_uint8 src,
|
||||
const picoos_uint8 fol1,
|
||||
const picoos_uint8 fol2,
|
||||
const picoos_uint16 nrwordspre,
|
||||
const picoos_uint16 nrwordsfol,
|
||||
const picoos_uint16 nrsyllsfol);
|
||||
|
||||
/* classify a previously constructed input vector using tree 'this'
|
||||
returns: TRUE if okay, FALSE otherwise
|
||||
*/
|
||||
picoos_uint8 picokdt_dtPHRclassify(const picokdt_DtPHR this);
|
||||
|
||||
/* decompose the tree output and return the class vector in dtres
|
||||
dtres: phrasing classification result
|
||||
returns: TRUE if okay, FALSE otherwise
|
||||
*/
|
||||
picoos_uint8 picokdt_dtPHRdecomposeOutClass(const picokdt_DtPHR this,
|
||||
picokdt_classify_result_t *dtres);
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* decision tree accentuation (ACC) functions */
|
||||
/* ************************************************************/
|
||||
|
||||
/* construct an ACC input vector (run in right-to-left mode)
|
||||
tree input vector: 0-1 POS for each of the two previous words
|
||||
2 POS for current word
|
||||
3-4 POS for each of the two following words
|
||||
5-6 history values (already predicted following)
|
||||
7 nr words left (previous) to any bound
|
||||
8 nr syllables left to any bound
|
||||
9 nr words right (following) to any bound
|
||||
10 nr syllables right to any bound
|
||||
11 nr words right to predicted "1" prominence (foot)
|
||||
12 nr syllables right to predicted "1" prominence (foot)
|
||||
pre2 - pre1: POS for the previous two words
|
||||
src: POS of current word
|
||||
fol1 - fol2: POS for the following two words
|
||||
hist1 - hist2: previously predicted ACC values
|
||||
nrwordspre: number of words left (previous) of current word
|
||||
nrsyllspre: number of syllables left (previous) of current word,
|
||||
incl. initial non-prim stress syllables of current word
|
||||
nrwordsfol: number of words right (following) of current word,
|
||||
incl. current word, up to next BOUND (any strength != 0)
|
||||
nrsyllsfol: number of syllables right (following) of current word,
|
||||
incl. syllables of current word starting with prim. stress
|
||||
syllable
|
||||
footwordsfol: nr of words to the following prominence '1'
|
||||
footsyllspre: nr of syllables to the previous prominence '1'
|
||||
returns: TRUE if okay, FALSE otherwise
|
||||
note: use PICOKDT_EPSILON for att 0-4 values outside context
|
||||
*/
|
||||
picoos_uint8 picokdt_dtACCconstructInVec(const picokdt_DtACC this,
|
||||
const picoos_uint8 pre2,
|
||||
const picoos_uint8 pre1,
|
||||
const picoos_uint8 src,
|
||||
const picoos_uint8 fol1,
|
||||
const picoos_uint8 fol2,
|
||||
const picoos_uint16 hist1,
|
||||
const picoos_uint16 hist2,
|
||||
const picoos_uint16 nrwordspre,
|
||||
const picoos_uint16 nrsyllspre,
|
||||
const picoos_uint16 nrwordsfol,
|
||||
const picoos_uint16 nrsyllsfol,
|
||||
const picoos_uint16 footwordsfol,
|
||||
const picoos_uint16 footsyllsfol);
|
||||
|
||||
/* classify a previously constructed input vector using tree 'this'
|
||||
treeout: direct tree output value
|
||||
returns: TRUE if okay, FALSE otherwise
|
||||
*/
|
||||
picoos_uint8 picokdt_dtACCclassify(const picokdt_DtACC this,
|
||||
picoos_uint16 *treeout);
|
||||
|
||||
/* decompose the tree output and return the class vector in dtres
|
||||
dtres: phrasing classification result
|
||||
returns: TRUE if okay, FALSE otherwise
|
||||
*/
|
||||
picoos_uint8 picokdt_dtACCdecomposeOutClass(const picokdt_DtACC this,
|
||||
picokdt_classify_result_t *dtres);
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* decision tree phono-acoustical model (PAM) functions */
|
||||
/* ************************************************************/
|
||||
|
||||
/* construct a Pam input vector and store the tree-specific encoded
|
||||
input vector in the tree object.
|
||||
vec: tree input vector, 60 single-byte-sized attributes
|
||||
veclen: length of vec in number of bytes
|
||||
returns: TRUE if okay, FALSE otherwise
|
||||
*/
|
||||
picoos_uint8 picokdt_dtPAMconstructInVec(const picokdt_DtPAM this,
|
||||
const picoos_uint8 *vec,
|
||||
const picoos_uint8 veclen);
|
||||
|
||||
/* classify a previously constructed input vector using tree 'this'
|
||||
returns: TRUE if okay, FALSE otherwise
|
||||
*/
|
||||
picoos_uint8 picokdt_dtPAMclassify(const picokdt_DtPAM this);
|
||||
|
||||
/* decompose the tree output and return the class in dtres
|
||||
dtres: phones vector classification result
|
||||
returns: TRUE if okay, FALSE otherwise
|
||||
*/
|
||||
picoos_uint8 picokdt_dtPAMdecomposeOutClass(const picokdt_DtPAM this,
|
||||
picokdt_classify_result_t *dtres);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /*PICOKDT_H_*/
|
||||
@@ -0,0 +1,438 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picokfst.c
|
||||
*
|
||||
* FST knowledge loading and access
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
#include "picoos.h"
|
||||
#include "picodbg.h"
|
||||
#include "picoknow.h"
|
||||
#include "picokfst.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define FileHdrSize 4 /* size of FST file header */
|
||||
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* function to create specialized kb, */
|
||||
/* to be used by picorsrc only */
|
||||
/* ************************************************************/
|
||||
|
||||
/** object : FSTKnowledgeBase
|
||||
* shortcut : kfst
|
||||
* derived from : picoknow_KnowledgeBase
|
||||
*/
|
||||
|
||||
typedef struct kfst_subobj * kfst_SubObj;
|
||||
|
||||
typedef struct kfst_subobj{
|
||||
picoos_uint8 * fstStream; /* the byte stream base address */
|
||||
picoos_int32 hdrLen; /* length of file header */
|
||||
picoos_int32 transductionMode; /* transduction mode to be used for FST */
|
||||
picoos_int32 nrClasses; /* nr of pair/transition classes in FST; class is in [1..nrClasses] */
|
||||
picoos_int32 nrStates; /* nr of states in FST; state is in [1..nrState] */
|
||||
picoos_int32 termClass; /* pair class of terminator symbol pair; probably obsolete */
|
||||
picoos_int32 alphaHashTabSize; /* size of pair alphabet hash table */
|
||||
picoos_int32 alphaHashTabPos; /* absolute address of the start of the pair alphabet */
|
||||
picoos_int32 transTabEntrySize; /* size in bytes of each transition table entry */
|
||||
picoos_int32 transTabPos; /* absolute address of the start of the transition table */
|
||||
picoos_int32 inEpsStateTabPos; /* absolute address of the start of the input epsilon transition table */
|
||||
picoos_int32 accStateTabPos; /* absolute address of the table of accepting states */
|
||||
} kfst_subobj_t;
|
||||
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* primitives for reading from byte stream */
|
||||
/* ************************************************************/
|
||||
|
||||
/* Converts 'nrBytes' bytes starting at position '*pos' in byte stream 'stream' into unsigned number 'num'.
|
||||
'*pos' is modified to the position right after the number */
|
||||
static void FixedBytesToUnsignedNum (picoos_uint8 * stream, picoos_uint8 nrBytes, picoos_uint32 * pos, picoos_uint32 * num)
|
||||
{
|
||||
picoos_int32 i;
|
||||
|
||||
(*num) = 0;
|
||||
for (i = 0; i < nrBytes; i++) {
|
||||
(*num) = ((*num) << 8) + (picoos_uint32)stream[*pos];
|
||||
(*pos)++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Converts 'nrBytes' bytes starting at position '*pos' in byte stream 'stream' into signed number 'num'.
|
||||
'*pos' is modified to the position right after the number */
|
||||
static void FixedBytesToSignedNum (picoos_uint8 * stream, picoos_uint8 nrBytes, picoos_uint32 * pos, picoos_int32 * num)
|
||||
{
|
||||
picoos_int32 i;
|
||||
picoos_uint32 val;
|
||||
|
||||
val = 0;
|
||||
for (i = 0; i < nrBytes; i++) {
|
||||
val = (val << 8) + (picoos_uint32)stream[*pos];
|
||||
(*pos)++;
|
||||
}
|
||||
if (val % 2 == 1) {
|
||||
/* negative number */
|
||||
(*num) = -((picoos_int32)((val - 1) / 2)) - 1;
|
||||
} else {
|
||||
/* positive number */
|
||||
(*num) = val / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Converts varying-sized sequence of bytes starting at position '*pos' in byte stream 'stream'
|
||||
into (signed) number 'num'. '*pos' is modified to the position right after the number. */
|
||||
static void BytesToNum (picoos_uint8 * stream, picoos_uint32 * pos, picoos_int32 * num)
|
||||
{
|
||||
picoos_uint32 val;
|
||||
picoos_uint32 b;
|
||||
|
||||
val = 0;
|
||||
b = (picoos_uint32)stream[*pos];
|
||||
(*pos)++;
|
||||
while (b < 128) {
|
||||
val = (val << 7) + b;
|
||||
b = (picoos_uint32)stream[*pos];
|
||||
(*pos)++;
|
||||
}
|
||||
val = (val << 7) + (b - 128);
|
||||
if (val % 2 == 1) {
|
||||
/* negative number */
|
||||
(*num) = -((picoos_int32)((val - 1) / 2)) - 1;
|
||||
} else {
|
||||
/* positive number */
|
||||
(*num) = val / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* setting up FST from byte stream */
|
||||
/* ************************************************************/
|
||||
|
||||
static pico_status_t kfstInitialize(register picoknow_KnowledgeBase this,
|
||||
picoos_Common common)
|
||||
{
|
||||
picoos_uint32 curpos;
|
||||
picoos_int32 offs;
|
||||
kfst_subobj_t * kfst;
|
||||
|
||||
PICODBG_DEBUG(("kfstInitialize -- start\n"));
|
||||
|
||||
if (NULL == this || NULL == this->subObj) {
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_KB_MISSING, NULL,
|
||||
NULL);
|
||||
}
|
||||
kfst = (kfst_subobj_t *) this->subObj;
|
||||
|
||||
/* +CT+ */
|
||||
kfst->fstStream = this->base;
|
||||
PICODBG_TRACE(("base: %d\n",this->base));
|
||||
kfst->hdrLen = FileHdrSize;
|
||||
curpos = kfst->hdrLen;
|
||||
BytesToNum(kfst->fstStream,& curpos,& kfst->transductionMode);
|
||||
BytesToNum(kfst->fstStream,& curpos,& kfst->nrClasses);
|
||||
BytesToNum(kfst->fstStream,& curpos,& kfst->nrStates);
|
||||
BytesToNum(kfst->fstStream,& curpos,& kfst->termClass);
|
||||
BytesToNum(kfst->fstStream,& curpos,& kfst->alphaHashTabSize);
|
||||
BytesToNum(kfst->fstStream,& curpos,& offs);
|
||||
kfst->alphaHashTabPos = kfst->hdrLen + offs;
|
||||
BytesToNum(kfst->fstStream,& curpos,& kfst->transTabEntrySize);
|
||||
BytesToNum(kfst->fstStream,& curpos,& offs);
|
||||
kfst->transTabPos = kfst->hdrLen + offs;
|
||||
BytesToNum(kfst->fstStream,& curpos,& offs);
|
||||
kfst->inEpsStateTabPos = kfst->hdrLen + offs;
|
||||
BytesToNum(kfst->fstStream,& curpos,& offs);
|
||||
kfst->accStateTabPos = kfst->hdrLen + offs;
|
||||
/* -CT- */
|
||||
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
static pico_status_t kfstSubObjDeallocate(register picoknow_KnowledgeBase this,
|
||||
picoos_MemoryManager mm)
|
||||
{
|
||||
if (NULL != this) {
|
||||
picoos_deallocate(mm, (void *) &this->subObj);
|
||||
}
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
/* calculates a small number of data (e.g. addresses) from kb for fast access.
|
||||
* This data is encapsulated in a picokfst_FST that can later be retrieved
|
||||
* with picokfst_getFST. */
|
||||
pico_status_t picokfst_specializeFSTKnowledgeBase(picoknow_KnowledgeBase this,
|
||||
picoos_Common common)
|
||||
{
|
||||
pico_status_t status;
|
||||
|
||||
if (NULL == this) {
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_KB_MISSING, NULL, NULL);
|
||||
}
|
||||
if (0 < this->size) {
|
||||
/* not a dummy kb */
|
||||
this->subDeallocate = kfstSubObjDeallocate;
|
||||
|
||||
this->subObj = picoos_allocate(common->mm, sizeof(kfst_subobj_t));
|
||||
|
||||
if (NULL == this->subObj) {
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_OUT_OF_MEM, NULL, NULL);
|
||||
}
|
||||
status = kfstInitialize(this, common);
|
||||
if (PICO_OK != status) {
|
||||
picoos_deallocate(common->mm,(void **)&this->subObj);
|
||||
}
|
||||
}
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* FST type and getFST function */
|
||||
/* ************************************************************/
|
||||
|
||||
|
||||
|
||||
/* return kb FST for usage in PU */
|
||||
picokfst_FST picokfst_getFST(picoknow_KnowledgeBase this)
|
||||
{
|
||||
if (NULL == this) {
|
||||
return NULL;
|
||||
} else {
|
||||
return (picokfst_FST) this->subObj;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* FST access methods */
|
||||
/* ************************************************************/
|
||||
|
||||
|
||||
/* see description in header file */
|
||||
extern picoos_uint8 picokfst_kfstGetTransductionMode(picokfst_FST this)
|
||||
{
|
||||
kfst_SubObj fst = (kfst_SubObj) this;
|
||||
if (fst != NULL) {
|
||||
return fst->transductionMode;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* see description in header file */
|
||||
extern void picokfst_kfstGetFSTSizes (picokfst_FST this, picoos_int32 *nrStates, picoos_int32 *nrClasses)
|
||||
{
|
||||
kfst_SubObj fst = (kfst_SubObj) this;
|
||||
if (fst != NULL) {
|
||||
*nrStates = fst->nrStates;
|
||||
*nrClasses = fst->nrClasses;
|
||||
} else {
|
||||
*nrStates = 0;
|
||||
*nrClasses = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* see description in header file */
|
||||
extern void picokfst_kfstStartPairSearch (picokfst_FST this, picokfst_symid_t inSym,
|
||||
picoos_bool * inSymFound, picoos_int32 * searchState)
|
||||
{
|
||||
picoos_uint32 pos;
|
||||
picoos_int32 offs;
|
||||
picoos_int32 h;
|
||||
picoos_int32 inSymCellPos;
|
||||
picoos_int32 inSymX;
|
||||
picoos_int32 nextSameHashInSymOffs;
|
||||
|
||||
kfst_SubObj fst = (kfst_SubObj) this;
|
||||
(*searchState) = -1;
|
||||
(*inSymFound) = 0;
|
||||
h = inSym % fst->alphaHashTabSize;
|
||||
pos = fst->alphaHashTabPos + (h * 4);
|
||||
FixedBytesToSignedNum(fst->fstStream,4,& pos,& offs);
|
||||
if (offs > 0) {
|
||||
inSymCellPos = fst->alphaHashTabPos + offs;
|
||||
pos = inSymCellPos;
|
||||
BytesToNum(fst->fstStream,& pos,& inSymX);
|
||||
BytesToNum(fst->fstStream,& pos,& nextSameHashInSymOffs);
|
||||
while ((inSymX != inSym) && (nextSameHashInSymOffs > 0)) {
|
||||
inSymCellPos = inSymCellPos + nextSameHashInSymOffs;
|
||||
pos = inSymCellPos;
|
||||
BytesToNum(fst->fstStream,& pos,& inSymX);
|
||||
BytesToNum(fst->fstStream,& pos,& nextSameHashInSymOffs);
|
||||
}
|
||||
if (inSymX == inSym) {
|
||||
/* input symbol found; state is set to position after symbol cell */
|
||||
(*searchState) = pos;
|
||||
(*inSymFound) = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* see description in header file */
|
||||
extern void picokfst_kfstGetNextPair (picokfst_FST this, picoos_int32 * searchState,
|
||||
picoos_bool * pairFound,
|
||||
picokfst_symid_t * outSym, picokfst_class_t * pairClass)
|
||||
{
|
||||
picoos_uint32 pos;
|
||||
picoos_int32 val;
|
||||
|
||||
kfst_SubObj fst = (kfst_SubObj) this;
|
||||
if ((*searchState) < 0) {
|
||||
(*pairFound) = 0;
|
||||
(*outSym) = PICOKFST_SYMID_ILLEG;
|
||||
(*pairClass) = -1;
|
||||
} else {
|
||||
pos = (*searchState);
|
||||
BytesToNum(fst->fstStream,& pos,& val);
|
||||
*outSym = (picokfst_symid_t)val;
|
||||
if ((*outSym) != PICOKFST_SYMID_ILLEG) {
|
||||
BytesToNum(fst->fstStream,& pos,& val);
|
||||
*pairClass = (picokfst_class_t)val;
|
||||
(*pairFound) = 1;
|
||||
(*searchState) = pos;
|
||||
} else {
|
||||
(*pairFound) = 0;
|
||||
(*outSym) = PICOKFST_SYMID_ILLEG;
|
||||
(*pairClass) = -1;
|
||||
(*searchState) = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* see description in header file */
|
||||
extern void picokfst_kfstGetTrans (picokfst_FST this, picokfst_state_t startState, picokfst_class_t transClass,
|
||||
picokfst_state_t * endState)
|
||||
{
|
||||
|
||||
picoos_uint32 pos;
|
||||
picoos_int32 index;
|
||||
picoos_uint32 endStateX;
|
||||
|
||||
kfst_SubObj fst = (kfst_SubObj) this;
|
||||
if ((startState < 1) || (startState > fst->nrStates) || (transClass < 1) || (transClass > fst->nrClasses)) {
|
||||
(*endState) = 0;
|
||||
} else {
|
||||
index = (startState - 1) * fst->nrClasses + transClass - 1;
|
||||
pos = fst->transTabPos + (index * fst->transTabEntrySize);
|
||||
FixedBytesToUnsignedNum(fst->fstStream,fst->transTabEntrySize,& pos,& endStateX);
|
||||
(*endState) = endStateX;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* see description in header file */
|
||||
extern void picokfst_kfstStartInEpsTransSearch (picokfst_FST this, picokfst_state_t startState,
|
||||
picoos_bool * inEpsTransFound, picoos_int32 * searchState)
|
||||
{
|
||||
|
||||
picoos_int32 offs;
|
||||
picoos_uint32 pos;
|
||||
|
||||
kfst_SubObj fst = (kfst_SubObj) this;
|
||||
(*searchState) = -1;
|
||||
(*inEpsTransFound) = 0;
|
||||
if ((startState > 0) && (startState <= fst->nrStates)) {
|
||||
pos = fst->inEpsStateTabPos + (startState - 1) * 4;
|
||||
FixedBytesToSignedNum(fst->fstStream,4,& pos,& offs);
|
||||
if (offs > 0) {
|
||||
(*searchState) = fst->inEpsStateTabPos + offs;
|
||||
(*inEpsTransFound) = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* see description in header file */
|
||||
extern void picokfst_kfstGetNextInEpsTrans (picokfst_FST this, picoos_int32 * searchState,
|
||||
picoos_bool * inEpsTransFound,
|
||||
picokfst_symid_t * outSym, picokfst_state_t * endState)
|
||||
{
|
||||
picoos_uint32 pos;
|
||||
picoos_int32 val;
|
||||
|
||||
kfst_SubObj fst = (kfst_SubObj) this;
|
||||
if ((*searchState) < 0) {
|
||||
(*inEpsTransFound) = 0;
|
||||
(*outSym) = PICOKFST_SYMID_ILLEG;
|
||||
(*endState) = 0;
|
||||
} else {
|
||||
pos = (*searchState);
|
||||
BytesToNum(fst->fstStream,& pos,& val);
|
||||
*outSym = (picokfst_symid_t)val;
|
||||
if ((*outSym) != PICOKFST_SYMID_ILLEG) {
|
||||
BytesToNum(fst->fstStream,& pos,& val);
|
||||
*endState = (picokfst_state_t)val;
|
||||
(*inEpsTransFound) = 1;
|
||||
(*searchState) = pos;
|
||||
} else {
|
||||
(*inEpsTransFound) = 0;
|
||||
(*outSym) = PICOKFST_SYMID_ILLEG;
|
||||
(*endState) = 0;
|
||||
(*searchState) = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* see description in header file */
|
||||
extern picoos_bool picokfst_kfstIsAcceptingState (picokfst_FST this, picokfst_state_t state)
|
||||
{
|
||||
|
||||
picoos_uint32 pos;
|
||||
picoos_uint32 val;
|
||||
|
||||
kfst_SubObj fst = (kfst_SubObj) this;
|
||||
if ((state > 0) && (state <= fst->nrStates)) {
|
||||
pos = fst->accStateTabPos + (state - 1);
|
||||
FixedBytesToUnsignedNum(fst->fstStream,1,& pos,& val);
|
||||
return (val == 1);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* End picofst.c */
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picokfst.h
|
||||
*
|
||||
* FST knowledge loading and access
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
#ifndef PICOKFST_H_
|
||||
#define PICOKFST_H_
|
||||
|
||||
#include "picodefs.h"
|
||||
#include "picodbg.h"
|
||||
#include "picoos.h"
|
||||
#include "picoknow.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef picoos_int16 picokfst_symid_t; /* type of symbol identifiers */
|
||||
typedef picoos_int16 picokfst_class_t; /* type of symbol pair classes */
|
||||
typedef picoos_int16 picokfst_state_t; /* type of states */
|
||||
|
||||
#define PICOKFST_SYMID_EPS (picokfst_symid_t) 0 /* epsilon symbol id */
|
||||
#define PICOKFST_SYMID_ILLEG (picokfst_symid_t) -1 /* illegal symbol id */
|
||||
|
||||
/**
|
||||
* @addtogroup picokfst
|
||||
*
|
||||
* Mapping of values to FST symbol id (relevant for compiling the FST) \n
|
||||
* Value FST symbol id \n
|
||||
* -------------------------------------- \n
|
||||
* phoneme_id -> phoneme_id + 256 * PICOKFST_PLANE_PHONEMES \n
|
||||
* accentlevel_id -> accentlevel_id + 256 * PICOKFST_PLANE_ACCENTS \n
|
||||
* POS_id -> POS_id + 256 * PICOKFST_PLANE_POS \n
|
||||
* pb_strength_id -> pb_strength_id + 256 * PICOKFST_PLANE_PB_STRENGTHS \n
|
||||
* phon_term_id -> phon_term_id + 256 * PICOKFST_PLANE_INTERN \n
|
||||
*/
|
||||
enum picokfst_symbol_plane {
|
||||
PICOKFST_PLANE_PHONEMES = 0, /* phoneme plane */
|
||||
PICOKFST_PLANE_ASCII = 1, /* "ascii" plane (values > 127 may be used internally) */
|
||||
PICOKFST_PLANE_XSAMPA = 2, /* x-sampa primitives plane (pico-specific table) */
|
||||
PICOKFST_PLANE_ACCENTS = 4, /* accent plane */
|
||||
PICOKFST_PLANE_POS = 5, /* part of speech plane */
|
||||
PICOKFST_PLANE_PB_STRENGTHS = 6, /* phrase boundary strength plane */
|
||||
PICOKFST_PLANE_INTERN = 7 /* internal plane, e.g. phonStartId, phonTermId */
|
||||
};
|
||||
|
||||
/* to be used as bit set, e.g.
|
||||
* picoos_uint8 transductionMode = PICOKFST_TRANSMODE_NEWSYMS | PICOKFST_TRANSMODE_POSUSED;
|
||||
*/
|
||||
enum picofst_transduction_mode {
|
||||
PICOKFST_TRANSMODE_NEWSYMS = 1, /* e.g. {#WB},{#PB-S},{#PB-W},{#ACC0},{#ACC1},{#ACC2},{#ACC3}, */
|
||||
PICOKFST_TRANSMODE_POSUSED = 2 /* FST contains Part Of Speech symbols */
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* function to create specialized kb, */
|
||||
/* to be used by knowledge layer (picorsrc) only */
|
||||
/* ************************************************************/
|
||||
|
||||
/* calculates a small number of data (e.g. addresses) from kb for fast access.
|
||||
* This data is encapsulated in a picokfst_FST that can later be retrieved
|
||||
* with picokfst_getFST. */
|
||||
pico_status_t picokfst_specializeFSTKnowledgeBase(picoknow_KnowledgeBase this,
|
||||
picoos_Common common);
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* FST type and getFST function */
|
||||
/* ************************************************************/
|
||||
|
||||
/* FST type */
|
||||
typedef struct picokfst_fst * picokfst_FST;
|
||||
|
||||
/* return kb FST for usage in PU */
|
||||
picokfst_FST picokfst_getFST(picoknow_KnowledgeBase this);
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* FST access methods */
|
||||
/* ************************************************************/
|
||||
|
||||
/* returns transduction mode specified with rule sources;
|
||||
result to be interpreted as set of picofst_transduction_mode */
|
||||
picoos_uint8 picokfst_kfstGetTransductionMode(picokfst_FST this);
|
||||
|
||||
/* returns number of states and number of pair classes in FST;
|
||||
legal states are 1..nrStates, legal classes are 1..nrClasses */
|
||||
void picokfst_kfstGetFSTSizes (picokfst_FST this, picoos_int32 *nrStates, picoos_int32 *nrClasses);
|
||||
|
||||
/* starts search for all pairs with input symbol 'inSym'; '*inSymFound' returns whether
|
||||
such pairs exist at all; '*searchState' returns a search state to be used in
|
||||
subsequent calls to function 'picokfst_kfstGetNextPair', which must be used
|
||||
to get the symbol pairs */
|
||||
void picokfst_kfstStartPairSearch (picokfst_FST this, picokfst_symid_t inSym,
|
||||
picoos_bool * inSymFound, picoos_int32 * searchState);
|
||||
|
||||
/* gets next pair for input symbol specified with preceding call to 'picokfst_kfstStartPairSearch';
|
||||
'*searchState' maintains the search state, 'pairFound' returns whether any more pair was found,
|
||||
'*outSym' returns the output symbol of the found pair, and '*pairClass' returns the
|
||||
transition class of the found symbol pair */
|
||||
void picokfst_kfstGetNextPair (picokfst_FST this, picoos_int32 * searchState,
|
||||
picoos_bool * pairFound,
|
||||
picokfst_symid_t * outSym, picokfst_class_t * pairClass);
|
||||
|
||||
/* attempts to do FST transition from state 'startState' with pair class 'transClass';
|
||||
if such a transition exists, 'endState' returns the end state of the transition (> 0),
|
||||
otherwise 'endState' returns <= 0 */
|
||||
void picokfst_kfstGetTrans (picokfst_FST this, picokfst_state_t startState, picokfst_class_t transClass,
|
||||
picokfst_state_t * endState);
|
||||
|
||||
/* starts search for all pairs with input epsilon symbol and all correponding
|
||||
FST transitions starting in state 'startState'; to be used for fast
|
||||
computation of epsilon closures;
|
||||
'*inEpsTransFound' returns whether any such transition was found at all;
|
||||
if so, '*searchState' returns a search state to be used in subsequent calls
|
||||
to 'picokfst_kfstGetNextInEpsTrans' */
|
||||
void picokfst_kfstStartInEpsTransSearch (picokfst_FST this, picokfst_state_t startState,
|
||||
picoos_bool * inEpsTransFound, picoos_int32 * searchState);
|
||||
|
||||
/* gets next FST transition with a pair with empty input symbol starting from a state
|
||||
previoulsy specified in 'picokfst_kfstStartInEpsTransSearch';
|
||||
'*searchState' maintains the search state, '*inEpsTransFound' returns
|
||||
whether a new transition with input epsilon was found, '*outSym 'returns
|
||||
the output symbol of the found pair, and '*endState' returns the end state
|
||||
of the found transition with that pair */
|
||||
void picokfst_kfstGetNextInEpsTrans (picokfst_FST this, picoos_int32 * searchState,
|
||||
picoos_bool * inEpsTransFound,
|
||||
picokfst_symid_t * outSym, picokfst_state_t * endState);
|
||||
|
||||
/* returns whether 'state' is an accepting state of FST; originally, only
|
||||
state 1 was an accepting state; however, in order to remove the need to
|
||||
always do a last transition with a termination symbol pair, this function
|
||||
defines a state as an accepting state if there is transition to state 1
|
||||
with the terminator symbol pair */
|
||||
picoos_bool picokfst_kfstIsAcceptingState (picokfst_FST this, picokfst_state_t state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*PICOKFST_H_*/
|
||||
@@ -0,0 +1,572 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picoklex.c
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
#include "picoos.h"
|
||||
#include "picodbg.h"
|
||||
#include "picodata.h"
|
||||
#include "picoknow.h"
|
||||
#include "picoklex.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ************************************************************/
|
||||
/* lexicon */
|
||||
/* ************************************************************/
|
||||
|
||||
/**
|
||||
* @addtogroup picolex
|
||||
*
|
||||
overview:
|
||||
- lex consists of optional searchindex and a non-empty list of lexblocks
|
||||
- lexblocks are fixed size, at the start of a block there is also the
|
||||
start of an entry
|
||||
- using the searchindex a unambiguous lexblock can be determined which
|
||||
contains the entry (or there is no entry)
|
||||
- one lex entry has POS GRAPH PHON, all mandatory, but
|
||||
- PHON can be empty string -> no pronunciation in the resulting TTS output
|
||||
- PHON can be :G2P -> use G2P later to add pronunciation
|
||||
- (POS,GRAPH) is a uniq key (only one entry allowed)
|
||||
- (GRAPH) is almost a uniq key (2-4 entries with the same GRAPH, and
|
||||
differing POS and differing PHON possible)
|
||||
- for one graph we can have two or three solutions from the lex
|
||||
which all need to be passed on the the next PU
|
||||
- in this case GRAPH, POS, and PHON all must be available in lex
|
||||
|
||||
sizing:
|
||||
- 3 bytes entry index -> 16MB addressable
|
||||
- 2 bytes searchindex nr -> 64K blocks possible
|
||||
- 5 bytes per searchindex entry
|
||||
- 3 bytes for graph-prefix
|
||||
- 2 bytes blockadr in searchindex -> 64K blocks possible
|
||||
- lexblock size 512B:
|
||||
- 32M possible
|
||||
- with ~20 bytes per entry
|
||||
-> max. average of ~26 entries to be searched per lookup
|
||||
- overhead of ~10 bytes per block to sync with
|
||||
block boundaries
|
||||
- examples:
|
||||
- 500KB lex -> 1000 blocks,
|
||||
1000 entries in searchindex, ~25.6K lex-entries,
|
||||
- ~5KB searchindex
|
||||
~10KB overhead for block sync
|
||||
- 100KB lex -> 200 blocks,
|
||||
200 entries in searchindex, ~5.1K lex-entries,
|
||||
- ~1KB searchindex
|
||||
~2KB overhead for block sync
|
||||
|
||||
pil-file: lexicon knowledge base in binary form
|
||||
|
||||
lex-kb = content
|
||||
|
||||
content = searchindex {lexblock}1:NRBLOCKS2
|
||||
|
||||
lexblock = {lexentry}1: (lexblock size is fixed 512Bytes)
|
||||
|
||||
searchindex = NRBLOCKS2 {GRAPH1 GRAPH1 GRAPH1 LEXBLOCKIND2}=NRBLOCKS2
|
||||
|
||||
lexentry = LENGRAPH1 {GRAPH1}=LENGRAPH1-1
|
||||
LENPOSPHON1 POS1 {PHON1}=LENPOSPHON1-2
|
||||
|
||||
- special cases:
|
||||
- PHON is empty string (no pronunciation in the resulting TTS output):
|
||||
lexentry = LENGRAPH1 {GRAPH1}=LENGRAPH1-1 2 POS1
|
||||
- PHON can be :G2P -> use G2P later to add pronunciation:
|
||||
lexentry = LENGRAPH1 {GRAPH1}=LENGRAPH1-1 3 POS1 <reserved-phon-val=5>
|
||||
- multi-byte values always little endian
|
||||
*/
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* lexicon data defines */
|
||||
/* may not be changed with current implementation */
|
||||
/* ************************************************************/
|
||||
|
||||
/* nr bytes of nrblocks info */
|
||||
#define PICOKLEX_LEX_NRBLOCKS_SIZE 2
|
||||
|
||||
/* search index entry: - nr graphs
|
||||
- nr bytes of block index
|
||||
- nr bytes per entry, NRGRAPHS*INDSIZE */
|
||||
#define PICOKLEX_LEX_SIE_NRGRAPHS 3
|
||||
#define PICOKLEX_LEX_SIE_INDSIZE 2
|
||||
#define PICOKLEX_LEX_SIE_SIZE 5
|
||||
|
||||
/* nr of bytes per lexblock */
|
||||
#define PICOKLEX_LEXBLOCK_SIZE 512
|
||||
|
||||
|
||||
/* reserved values in klex to indicate :G2P needed for a lexentry */
|
||||
#define PICOKLEX_NEEDS_G2P 5
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* lexicon type and loading */
|
||||
/* ************************************************************/
|
||||
|
||||
/** object : LexKnowledgeBase
|
||||
* shortcut : klex
|
||||
* derived from : picoknow_KnowledgeBase
|
||||
*/
|
||||
|
||||
typedef struct klex_subobj *klex_SubObj;
|
||||
|
||||
typedef struct klex_subobj
|
||||
{
|
||||
picoos_uint16 nrblocks; /* nr lexblocks = nr eles in searchind */
|
||||
picoos_uint8 *searchind;
|
||||
picoos_uint8 *lexblocks;
|
||||
} klex_subobj_t;
|
||||
|
||||
|
||||
static pico_status_t klexInitialize(register picoknow_KnowledgeBase this,
|
||||
picoos_Common common)
|
||||
{
|
||||
picoos_uint32 curpos = 0;
|
||||
klex_subobj_t *klex;
|
||||
|
||||
PICODBG_DEBUG(("start"));
|
||||
|
||||
/* check whether (this->size != 0) done before calling this function */
|
||||
|
||||
if (NULL == this || NULL == this->subObj) {
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_KB_MISSING,
|
||||
NULL, NULL);
|
||||
}
|
||||
klex = (klex_subobj_t *) this->subObj;
|
||||
|
||||
if (PICO_OK == picoos_read_mem_pi_uint16(this->base, &curpos,
|
||||
&(klex->nrblocks))) {
|
||||
if (klex->nrblocks > 0) {
|
||||
PICODBG_DEBUG(("nr blocks: %i, curpos: %i", klex->nrblocks,curpos));
|
||||
klex->searchind = this->base + curpos;
|
||||
} else {
|
||||
klex->searchind = NULL;
|
||||
}
|
||||
klex->lexblocks = this->base + PICOKLEX_LEX_NRBLOCKS_SIZE +
|
||||
(klex->nrblocks * (PICOKLEX_LEX_SIE_SIZE));
|
||||
return PICO_OK;
|
||||
} else {
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_FILE_CORRUPT,
|
||||
NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static pico_status_t klexSubObjDeallocate(register picoknow_KnowledgeBase this,
|
||||
picoos_MemoryManager mm)
|
||||
{
|
||||
if (NULL != this) {
|
||||
picoos_deallocate(mm, (void *) &this->subObj);
|
||||
}
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
/* we don't offer a specialized constructor for a LexKnowledgeBase but
|
||||
* instead a "specializer" of an allready existing generic
|
||||
* picoknow_KnowledgeBase */
|
||||
|
||||
pico_status_t picoklex_specializeLexKnowledgeBase(picoknow_KnowledgeBase this,
|
||||
picoos_Common common)
|
||||
{
|
||||
if (NULL == this) {
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_KB_MISSING,
|
||||
NULL, NULL);
|
||||
}
|
||||
if (this->size > 0) {
|
||||
this->subDeallocate = klexSubObjDeallocate;
|
||||
this->subObj = picoos_allocate(common->mm, sizeof(klex_subobj_t));
|
||||
if (NULL == this->subObj) {
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_OUT_OF_MEM,
|
||||
NULL, NULL);
|
||||
}
|
||||
return klexInitialize(this, common);
|
||||
} else {
|
||||
/* some dummy klex */
|
||||
return PICO_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* for now we don't need to do anything special for the main lex */
|
||||
/*
|
||||
pico_status_t picoklex_specializeMainLexKnowledgeBase(
|
||||
picoknow_KnowledgeBase this,
|
||||
picoos_Common common)
|
||||
{
|
||||
return picoklex_specializeLexKnowledgeBase(this,common);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* lexicon getLex */
|
||||
/* ************************************************************/
|
||||
|
||||
picoklex_Lex picoklex_getLex(picoknow_KnowledgeBase this)
|
||||
{
|
||||
if (NULL == this) {
|
||||
return NULL;
|
||||
} else {
|
||||
return (picoklex_Lex) this->subObj;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* functions on searchindex */
|
||||
/* ************************************************************/
|
||||
|
||||
|
||||
static picoos_uint32 klex_getSearchIndexVal(const klex_SubObj this,
|
||||
picoos_uint16 index)
|
||||
{
|
||||
picoos_uint32 pos, val;
|
||||
pos = index * PICOKLEX_LEX_SIE_SIZE;
|
||||
val = this->searchind[pos];
|
||||
val = (val << 8) + this->searchind[pos + 1];
|
||||
val = (val << 8) + this->searchind[pos + 2];
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
/* Determine first lexblock containing entries for specified
|
||||
grapheme. */
|
||||
|
||||
static picoos_uint16 klex_getLexblockNr(const klex_SubObj this,
|
||||
const picoos_uint8 *graphsi) {
|
||||
/* graphsi is of len PICOKLEX_LEX_SI_NGRAPHS */
|
||||
picoos_int32 low, mid, high;
|
||||
picoos_uint32 searchval, indval;
|
||||
|
||||
/* PICOKLEX_LEX_SIE_NRGRAPHS */
|
||||
|
||||
/* convert graph-prefix to number with 'lexicographic' ordering */
|
||||
searchval = graphsi[0];
|
||||
searchval = (searchval << 8) + graphsi[1];
|
||||
searchval = (searchval << 8) + graphsi[2];
|
||||
|
||||
low = 0;
|
||||
high = this->nrblocks;
|
||||
|
||||
/* do binary search */
|
||||
while (low < high) {
|
||||
mid = (low + high) / 2;
|
||||
indval = klex_getSearchIndexVal(this, mid);
|
||||
if (indval < searchval) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
high = mid;
|
||||
}
|
||||
}
|
||||
PICODBG_ASSERT(high == low);
|
||||
/* low points to the first entry greater than or equal to searchval */
|
||||
|
||||
if (low < this->nrblocks) {
|
||||
indval = klex_getSearchIndexVal(this, low);
|
||||
if (indval > searchval) {
|
||||
low--;
|
||||
/* if there are identical elements in the search index we have
|
||||
to move to the first one */
|
||||
if (low > 0) {
|
||||
indval = klex_getSearchIndexVal(this, low);
|
||||
while (indval == klex_getSearchIndexVal(this, low-1)) {
|
||||
low--;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
low = this->nrblocks - 1;
|
||||
}
|
||||
|
||||
#if defined(PICO_DEBUG)
|
||||
{
|
||||
picoos_uint32 pos = low * PICOKLEX_LEX_SIE_SIZE;
|
||||
PICODBG_DEBUG(("binary search result is %c%c%c (%d)",
|
||||
this->searchind[pos], this->searchind[pos + 1],
|
||||
this->searchind[pos + 2], low));
|
||||
}
|
||||
#endif
|
||||
|
||||
return (picoos_uint16) low;
|
||||
}
|
||||
|
||||
|
||||
/* Determine number of adjacent lexblocks containing entries for
|
||||
the same grapheme search prefix (identified by search index). */
|
||||
|
||||
static picoos_uint16 klex_getLexblockRange(const klex_SubObj this,
|
||||
picoos_uint16 index)
|
||||
{
|
||||
picoos_uint16 count;
|
||||
picoos_uint32 sval1, sval2;
|
||||
|
||||
sval1 = klex_getSearchIndexVal(this, index);
|
||||
|
||||
#if defined(PICO_DEBUG)
|
||||
/* 'index' must point to first lexblock of its kind */
|
||||
if (index > 0) {
|
||||
sval2 = klex_getSearchIndexVal(this, index - 1);
|
||||
PICODBG_ASSERT(sval1 != sval2);
|
||||
}
|
||||
#endif
|
||||
|
||||
index++;
|
||||
sval2 = klex_getSearchIndexVal(this, index);
|
||||
|
||||
count = 1;
|
||||
while (sval1 == sval2) {
|
||||
count++;
|
||||
index++;
|
||||
sval2 = klex_getSearchIndexVal(this, index);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* functions on single lexblock */
|
||||
/* ************************************************************/
|
||||
|
||||
static picoos_int8 klex_lexMatch(picoos_uint8 *lexentry,
|
||||
const picoos_uint8 *graph,
|
||||
const picoos_uint16 graphlen) {
|
||||
picoos_uint8 i;
|
||||
picoos_uint8 lexlen;
|
||||
picoos_uint8 *lexgraph;
|
||||
|
||||
lexlen = lexentry[0] - 1;
|
||||
lexgraph = &(lexentry[1]);
|
||||
for (i=0; (i<graphlen) && (i<lexlen); i++) {
|
||||
PICODBG_TRACE(("%d|%d graph|lex: %c|%c", graphlen, lexlen,
|
||||
graph[i], lexgraph[i]));
|
||||
if (lexgraph[i] < graph[i]) {
|
||||
return -1;
|
||||
} else if (lexgraph[i] > graph[i]) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (graphlen == lexlen) {
|
||||
return 0;
|
||||
} else if (lexlen < graphlen) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void klex_setLexResult(const picoos_uint8 *lexentry,
|
||||
const picoos_uint32 lexpos,
|
||||
picoklex_lexl_result_t *lexres) {
|
||||
picoos_uint8 i;
|
||||
|
||||
/* check if :G2P */
|
||||
if ((2 < (lexentry[lexentry[0]])) && ((lexentry[lexentry[0] + 2]) == PICOKLEX_NEEDS_G2P)) {
|
||||
/* set pos */
|
||||
lexres->posind[0] = lexentry[lexentry[0] + 1];
|
||||
/* set rest */
|
||||
lexres->phonfound = FALSE;
|
||||
lexres->posindlen = 1;
|
||||
lexres->nrres = 1;
|
||||
PICODBG_DEBUG(("result %d :G2P", lexres->nrres));
|
||||
} else {
|
||||
i = lexres->nrres * (PICOKLEX_POSIND_SIZE);
|
||||
lexres->posindlen += PICOKLEX_POSIND_SIZE;
|
||||
lexres->phonfound = TRUE;
|
||||
/* set pos */
|
||||
lexres->posind[i++] = lexentry[lexentry[0] + 1];
|
||||
/* set ind, PICOKLEX_IND_SIZE */
|
||||
lexres->posind[i++] = 0x000000ff & (lexpos);
|
||||
lexres->posind[i++] = 0x000000ff & (lexpos >> 8);
|
||||
lexres->posind[i] = 0x000000ff & (lexpos >> 16);
|
||||
lexres->nrres++;
|
||||
PICODBG_DEBUG(("result %d", lexres->nrres));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void klex_lexblockLookup(klex_SubObj this,
|
||||
const picoos_uint32 lexposStart,
|
||||
const picoos_uint32 lexposEnd,
|
||||
const picoos_uint8 *graph,
|
||||
const picoos_uint16 graphlen,
|
||||
picoklex_lexl_result_t *lexres) {
|
||||
picoos_uint32 lexpos;
|
||||
picoos_int8 rv;
|
||||
|
||||
lexres->nrres = 0;
|
||||
|
||||
lexpos = lexposStart;
|
||||
rv = -1;
|
||||
while ((rv < 0) && (lexpos < lexposEnd)) {
|
||||
|
||||
rv = klex_lexMatch(&(this->lexblocks[lexpos]), graph, graphlen);
|
||||
|
||||
if (rv == 0) { /* found */
|
||||
klex_setLexResult(&(this->lexblocks[lexpos]), lexpos, lexres);
|
||||
if (lexres->phonfound) {
|
||||
/* look for more results, up to MAX_NRRES, don't even
|
||||
check if more results would be available */
|
||||
while ((lexres->nrres < PICOKLEX_MAX_NRRES) &&
|
||||
(lexpos < lexposEnd)) {
|
||||
lexpos += this->lexblocks[lexpos];
|
||||
lexpos += this->lexblocks[lexpos];
|
||||
/* if there are no more entries in this block, advance
|
||||
to next block by skipping all zeros */
|
||||
while ((this->lexblocks[lexpos] == 0) &&
|
||||
(lexpos < lexposEnd)) {
|
||||
lexpos++;
|
||||
}
|
||||
if (lexpos < lexposEnd) {
|
||||
if (klex_lexMatch(&(this->lexblocks[lexpos]), graph,
|
||||
graphlen) == 0) {
|
||||
klex_setLexResult(&(this->lexblocks[lexpos]),
|
||||
lexpos, lexres);
|
||||
} else {
|
||||
/* no more results, quit loop */
|
||||
lexpos = lexposEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* :G2P mark */
|
||||
}
|
||||
} else if (rv < 0) {
|
||||
/* not found, goto next entry */
|
||||
lexpos += this->lexblocks[lexpos];
|
||||
lexpos += this->lexblocks[lexpos];
|
||||
/* if there are no more entries in this block, advance
|
||||
to next block by skipping all zeros */
|
||||
while ((this->lexblocks[lexpos] == 0) && (lexpos < lexposEnd)) {
|
||||
lexpos++;
|
||||
}
|
||||
} else {
|
||||
/* rv > 0, not found, won't show up later in block */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* lexicon lookup functions */
|
||||
/* ************************************************************/
|
||||
|
||||
picoos_uint8 picoklex_lexLookup(const picoklex_Lex this,
|
||||
const picoos_uint8 *graph,
|
||||
const picoos_uint16 graphlen,
|
||||
picoklex_lexl_result_t *lexres) {
|
||||
picoos_uint16 lbnr, lbc;
|
||||
picoos_uint32 lexposStart, lexposEnd;
|
||||
picoos_uint8 i;
|
||||
picoos_uint8 tgraph[PICOKLEX_LEX_SIE_NRGRAPHS];
|
||||
klex_SubObj klex = (klex_SubObj) this;
|
||||
|
||||
if (NULL == klex) {
|
||||
PICODBG_ERROR(("no lexicon loaded"));
|
||||
/* no exception here needed, already checked at initialization */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
lexres->nrres = 0;
|
||||
lexres->posindlen = 0;
|
||||
lexres->phonfound = FALSE;
|
||||
|
||||
for (i = 0; i<PICOKLEX_LEX_SIE_NRGRAPHS; i++) {
|
||||
if (i < graphlen) {
|
||||
tgraph[i] = graph[i];
|
||||
} else {
|
||||
tgraph[i] = '\0';
|
||||
}
|
||||
}
|
||||
PICODBG_DEBUG(("tgraph: %c%c%c", tgraph[0],tgraph[1],tgraph[2]));
|
||||
|
||||
if ((klex->nrblocks) == 0) {
|
||||
/* no searchindex, no lexblock */
|
||||
PICODBG_WARN(("no searchindex, no lexblock"));
|
||||
return FALSE;
|
||||
} else {
|
||||
lbnr = klex_getLexblockNr(klex, tgraph);
|
||||
PICODBG_ASSERT(lbnr < klex->nrblocks);
|
||||
lbc = klex_getLexblockRange(klex, lbnr);
|
||||
PICODBG_ASSERT((lbc >= 1) && (lbc <= klex->nrblocks));
|
||||
}
|
||||
PICODBG_DEBUG(("lexblock nr: %d (#%d)", lbnr, lbc));
|
||||
|
||||
lexposStart = lbnr * PICOKLEX_LEXBLOCK_SIZE;
|
||||
lexposEnd = lexposStart + lbc * PICOKLEX_LEXBLOCK_SIZE;
|
||||
|
||||
PICODBG_DEBUG(("lookup start, lexpos range %d..%d", lexposStart,lexposEnd));
|
||||
klex_lexblockLookup(klex, lexposStart, lexposEnd, graph, graphlen, lexres);
|
||||
PICODBG_DEBUG(("lookup done, %d found", lexres->nrres));
|
||||
|
||||
return (lexres->nrres > 0);
|
||||
}
|
||||
|
||||
|
||||
picoos_uint8 picoklex_lexIndLookup(const picoklex_Lex this,
|
||||
const picoos_uint8 *ind,
|
||||
const picoos_uint8 indlen,
|
||||
picoos_uint8 *pos,
|
||||
picoos_uint8 **phon,
|
||||
picoos_uint8 *phonlen) {
|
||||
picoos_uint32 pentry;
|
||||
klex_SubObj klex = (klex_SubObj) this;
|
||||
|
||||
/* check indlen */
|
||||
if (indlen != PICOKLEX_IND_SIZE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* PICOKLEX_IND_SIZE */
|
||||
pentry = 0x000000ff & (ind[0]);
|
||||
pentry |= ((picoos_uint32)(ind[1]) << 8);
|
||||
pentry |= ((picoos_uint32)(ind[2]) << 16);
|
||||
|
||||
/* check ind if it is within lexblocks byte stream, if not, return FALSE */
|
||||
if (pentry >= ((picoos_uint32)klex->nrblocks * PICOKLEX_LEXBLOCK_SIZE)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pentry += (klex->lexblocks[pentry]);
|
||||
*phonlen = (klex->lexblocks[pentry++]) - 2;
|
||||
*pos = klex->lexblocks[pentry++];
|
||||
*phon = &(klex->lexblocks[pentry]);
|
||||
|
||||
PICODBG_DEBUG(("pentry: %d, phonlen: %d", pentry, *phonlen));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* end */
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picoklex.h
|
||||
*
|
||||
* knowledge base: lexicon
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PICOKLEX_H_
|
||||
#define PICOKLEX_H_
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picoknow.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* function to create specialized kb, */
|
||||
/* to be used by picorsrc only */
|
||||
/* ************************************************************/
|
||||
|
||||
pico_status_t picoklex_specializeLexKnowledgeBase(picoknow_KnowledgeBase this,
|
||||
picoos_Common common);
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* lexicon type and getLex function */
|
||||
/* ************************************************************/
|
||||
|
||||
/* lexicon type */
|
||||
typedef struct picoklex_lex * picoklex_Lex;
|
||||
|
||||
/* return kb lex for usage in PU */
|
||||
picoklex_Lex picoklex_getLex(picoknow_KnowledgeBase this);
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* lexicon lookup result type */
|
||||
/* ************************************************************/
|
||||
|
||||
/* max nr of results */
|
||||
#define PICOKLEX_MAX_NRRES 4
|
||||
|
||||
/* nr of bytes used for pos and index, needs to fit in uint32, ie. max 4 */
|
||||
#define PICOKLEX_POSIND_SIZE 4
|
||||
/* nr of bytes used for index, needs to fit in uint32, ie. max 4 */
|
||||
#define PICOKLEX_IND_SIZE 3
|
||||
/* max len (in bytes) of ind, (PICOKLEX_MAX_NRRES * PICOKLEX_POSIND_SIZE) */
|
||||
#define PICOKLEX_POSIND_MAXLEN 16
|
||||
|
||||
|
||||
/* the lexicon lookup result(s) are stored in field posind, which
|
||||
contains a sequence of
|
||||
POS1-byte, IND1-bytes, POS2-byte, IND2-bytes, etc.
|
||||
|
||||
the IND-bytes are the byte position(s) in the lexblocks part of the
|
||||
lexicon byte stream, starting at picoklex_lex_t.lexblocks.
|
||||
|
||||
for lexentries without phones only the POS (there can be only one)
|
||||
is stored in posind, nrres equals one, and phonfound is FALSE.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
picoos_uint8 nrres; /* number of results, 0 of no entry found */
|
||||
picoos_uint8 posindlen; /* number of posind bytes */
|
||||
picoos_uint8 phonfound; /* phones found flag, TRUE if found */
|
||||
picoos_uint8 posind[PICOKLEX_POSIND_MAXLEN]; /* sequence of multi-ind,
|
||||
one per result */
|
||||
} picoklex_lexl_result_t;
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* lexicon lookup functions */
|
||||
/* ************************************************************/
|
||||
|
||||
/** lookup lex by graph; result(s) are in lexres, ie. the phones are
|
||||
not returned directly (because they are used later and space can be
|
||||
saved using indices first), lexres contains an index (or several)
|
||||
to the entry for later fast lookup once the phones are needed.
|
||||
PICOKLEX_IND_SIZE bytes are used for the index, these ind bytes are
|
||||
saved in the WORDINDEX items. If at least one entry is found TRUE
|
||||
is returned, FALSE otherwise */
|
||||
picoos_uint8 picoklex_lexLookup(const picoklex_Lex this,
|
||||
const picoos_uint8 *graph,
|
||||
const picoos_uint16 graphlen,
|
||||
picoklex_lexl_result_t *lexres);
|
||||
|
||||
/** lookup lex entry by index ind; ind is a sequence of bytes with
|
||||
length indlen (must be equal PICOKLEX_IND_SIZE) that is the content
|
||||
of a WORDINDEX item. Returns TRUE if okay, FALSE otherwise */
|
||||
picoos_uint8 picoklex_lexIndLookup(const picoklex_Lex this,
|
||||
const picoos_uint8 *ind,
|
||||
const picoos_uint8 indlen,
|
||||
picoos_uint8 *pos,
|
||||
picoos_uint8 **phon,
|
||||
picoos_uint8 *phonlen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*PICOKLEX_H_*/
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picoknow.c
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
#include "picodefs.h"
|
||||
#include "picoos.h"
|
||||
#include "picodbg.h"
|
||||
#include "picoknow.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** class : KnowledgeBase
|
||||
* shortcut : kb
|
||||
*
|
||||
*/
|
||||
extern picoknow_KnowledgeBase picoknow_newKnowledgeBase(picoos_MemoryManager mm)
|
||||
{
|
||||
picoknow_KnowledgeBase this;
|
||||
PICODBG_TRACE(("start"));
|
||||
|
||||
this = picoos_allocate(mm,sizeof(*this));
|
||||
if (NULL != this) {
|
||||
PICODBG_TRACE(("allocated KnowledgeBase at address %i with size %i",(picoos_uint32)this,sizeof(*this)));
|
||||
/* initialize */
|
||||
this->next = NULL;
|
||||
this->id = PICOKNOW_KBID_NULL;
|
||||
this->base = NULL;
|
||||
this->size = 0;
|
||||
this->subObj = NULL;
|
||||
this->subDeallocate = NULL;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
extern void picoknow_disposeKnowledgeBase(picoos_MemoryManager mm, picoknow_KnowledgeBase * this)
|
||||
{
|
||||
picoos_uint8 id;
|
||||
if (NULL != (*this)) {
|
||||
id = (*this)->id;
|
||||
PICODBG_TRACE(("disposing KnowledgeBase id=%i",id));
|
||||
/* terminate */
|
||||
if ((*this)->subObj != NULL) {
|
||||
(*this)->subDeallocate((*this),mm);
|
||||
}
|
||||
picoos_deallocate(mm,(void**)this);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* End picoknow.c */
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picoknow.h
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @addtogroup picoknow
|
||||
|
||||
* <b> Pico knowledge base </b>\n
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PICOKNOW_H_
|
||||
#define PICOKNOW_H_
|
||||
|
||||
#include "picodefs.h"
|
||||
#include "picoos.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum picoknow_kb_id {
|
||||
PICOKNOW_KBID_NULL = 0,
|
||||
/* base / tpp 1 - 7 */
|
||||
PICOKNOW_KBID_TPP_MAIN = 1,
|
||||
PICOKNOW_KBID_TAB_GRAPHS = 2,
|
||||
PICOKNOW_KBID_TAB_PHONES = 3,
|
||||
PICOKNOW_KBID_TAB_POS = 4,
|
||||
PICOKNOW_KBID_FIXED_IDS = 7,
|
||||
/* debug */
|
||||
PICOKNOW_KBID_DBG = 8,
|
||||
|
||||
/* textana 9 - 32 */
|
||||
PICOKNOW_KBID_LEX_MAIN = 9,
|
||||
PICOKNOW_KBID_DT_POSP = 10,
|
||||
PICOKNOW_KBID_DT_POSD = 11,
|
||||
PICOKNOW_KBID_DT_G2P = 12,
|
||||
PICOKNOW_KBID_FST_WPHO_1 = 13,
|
||||
PICOKNOW_KBID_FST_WPHO_2 = 14,
|
||||
PICOKNOW_KBID_FST_WPHO_3 = 15,
|
||||
PICOKNOW_KBID_FST_WPHO_4 = 16,
|
||||
PICOKNOW_KBID_FST_WPHO_5 = 17,
|
||||
PICOKNOW_KBID_DT_PHR = 18,
|
||||
PICOKNOW_KBID_DT_ACC = 19,
|
||||
PICOKNOW_KBID_FST_SPHO_1 = 20,
|
||||
PICOKNOW_KBID_FST_SPHO_2 = 21,
|
||||
PICOKNOW_KBID_FST_SPHO_3 = 22,
|
||||
PICOKNOW_KBID_FST_SPHO_4 = 23,
|
||||
PICOKNOW_KBID_FST_SPHO_5 = 24,
|
||||
|
||||
PICOKNOW_KBID_FST_XSAMPA_PARSE = 25,
|
||||
PICOKNOW_KBID_FST_SVOXPA_PARSE = 26,
|
||||
PICOKNOW_KBID_FST_XSAMPA2SVOXPA = 27,
|
||||
|
||||
PICOKNOW_KBID_FST_SPHO_6 = 28,
|
||||
PICOKNOW_KBID_FST_SPHO_7 = 29,
|
||||
PICOKNOW_KBID_FST_SPHO_8 = 30,
|
||||
PICOKNOW_KBID_FST_SPHO_9 = 31,
|
||||
PICOKNOW_KBID_FST_SPHO_10 = 32,
|
||||
|
||||
|
||||
/* siggen 33 - 48 */
|
||||
PICOKNOW_KBID_DT_DUR = 34,
|
||||
PICOKNOW_KBID_DT_LFZ1 = 35,
|
||||
PICOKNOW_KBID_DT_LFZ2 = 36,
|
||||
PICOKNOW_KBID_DT_LFZ3 = 37,
|
||||
PICOKNOW_KBID_DT_LFZ4 = 38,
|
||||
PICOKNOW_KBID_DT_LFZ5 = 39,
|
||||
PICOKNOW_KBID_DT_MGC1 = 40,
|
||||
PICOKNOW_KBID_DT_MGC2 = 41,
|
||||
PICOKNOW_KBID_DT_MGC3 = 42,
|
||||
PICOKNOW_KBID_DT_MGC4 = 43,
|
||||
PICOKNOW_KBID_DT_MGC5 = 44,
|
||||
PICOKNOW_KBID_PDF_DUR = 45,
|
||||
PICOKNOW_KBID_PDF_LFZ = 46,
|
||||
PICOKNOW_KBID_PDF_MGC = 47,
|
||||
PICOKNOW_KBID_PDF_PHS = 48,
|
||||
|
||||
/* user tpp 49 - 56 */
|
||||
PICOKNOW_KBID_TPP_USER_1 = 49,
|
||||
PICOKNOW_KBID_TPP_USER_2 = 50,
|
||||
|
||||
/* user lex 57 - 63 */
|
||||
PICOKNOW_KBID_LEX_USER_1 = 57,
|
||||
PICOKNOW_KBID_LEX_USER_2 = 58,
|
||||
|
||||
PICOKNOW_KBID_DUMMY = 127
|
||||
|
||||
} picoknow_kb_id_t;
|
||||
|
||||
#define PICOKNOW_DEFAULT_RESOURCE_NAME (picoos_char *) "__PICO_DEF_RSRC"
|
||||
|
||||
#define PICOKNOW_MAX_NUM_WPHO_FSTS 5
|
||||
#define PICOKNOW_MAX_NUM_SPHO_FSTS 10
|
||||
#define PICOKNOW_MAX_NUM_ULEX 2
|
||||
#define PICOKNOW_MAX_NUM_UTPP 2
|
||||
|
||||
#define PICOKNOW_KBID_WPHO_ARRAY { \
|
||||
PICOKNOW_KBID_FST_WPHO_1, \
|
||||
PICOKNOW_KBID_FST_WPHO_2, \
|
||||
PICOKNOW_KBID_FST_WPHO_3, \
|
||||
PICOKNOW_KBID_FST_WPHO_4, \
|
||||
PICOKNOW_KBID_FST_WPHO_5 \
|
||||
}
|
||||
|
||||
#define PICOKNOW_KBID_SPHO_ARRAY { \
|
||||
PICOKNOW_KBID_FST_SPHO_1, \
|
||||
PICOKNOW_KBID_FST_SPHO_2, \
|
||||
PICOKNOW_KBID_FST_SPHO_3, \
|
||||
PICOKNOW_KBID_FST_SPHO_4, \
|
||||
PICOKNOW_KBID_FST_SPHO_5, \
|
||||
PICOKNOW_KBID_FST_SPHO_6, \
|
||||
PICOKNOW_KBID_FST_SPHO_7, \
|
||||
PICOKNOW_KBID_FST_SPHO_8, \
|
||||
PICOKNOW_KBID_FST_SPHO_9, \
|
||||
PICOKNOW_KBID_FST_SPHO_10 \
|
||||
}
|
||||
|
||||
#define PICOKNOW_KBID_ULEX_ARRAY { \
|
||||
PICOKNOW_KBID_LEX_USER_1, \
|
||||
PICOKNOW_KBID_LEX_USER_2, \
|
||||
}
|
||||
|
||||
#define PICOKNOW_KBID_UTPP_ARRAY { \
|
||||
PICOKNOW_KBID_TPP_USER_1, \
|
||||
PICOKNOW_KBID_TPP_USER_2, \
|
||||
}
|
||||
|
||||
/* max size (including NULLC) of descriptive name corresponding to KBID */
|
||||
#define PICOKNOW_MAX_KB_NAME_SIZ 16
|
||||
|
||||
/* maximum number of kbs in one resource */
|
||||
#define PICOKNOW_MAX_NUM_RESOURCE_KBS 64
|
||||
|
||||
|
||||
/** class : KnowledgeBase
|
||||
* shortcut : kb
|
||||
*
|
||||
*/
|
||||
typedef struct picoknow_knowledge_base * picoknow_KnowledgeBase;
|
||||
|
||||
typedef pico_status_t (* picoknow_kbSubDeallocate) (register picoknow_KnowledgeBase this, picoos_MemoryManager mm);
|
||||
|
||||
typedef struct picoknow_knowledge_base {
|
||||
/* public */
|
||||
picoknow_KnowledgeBase next;
|
||||
picoknow_kb_id_t id;
|
||||
picoos_uint8 * base; /* start address */
|
||||
picoos_uint32 size; /* size */
|
||||
|
||||
/* protected */
|
||||
picoknow_kbSubDeallocate subDeallocate;
|
||||
void * subObj;
|
||||
} picoknow_knowledge_base_t;
|
||||
|
||||
extern picoknow_KnowledgeBase picoknow_newKnowledgeBase(picoos_MemoryManager mm);
|
||||
|
||||
extern void picoknow_disposeKnowledgeBase(picoos_MemoryManager mm, picoknow_KnowledgeBase * this);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*PICOKNOW_H_*/
|
||||
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picokpdf.c
|
||||
*
|
||||
* knowledge handling for pdf
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picodbg.h"
|
||||
#include "picoknow.h"
|
||||
#include "picokpdf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* pdf */
|
||||
/* ************************************************************/
|
||||
|
||||
/*
|
||||
* @addtogroup picokpdf
|
||||
*
|
||||
overview: format of knowledge base pdf file
|
||||
|
||||
This is the format for the dur pdf file:
|
||||
- Numframes: 1 uint16
|
||||
- Vecsize: 1 uint8
|
||||
- sampperframe: 1 uint8
|
||||
- Phonquantlen: 1 uint8
|
||||
- Phonquant: Phonquantlen uint8
|
||||
- Statequantlen: 1 uint8
|
||||
- Statequantlen: Statequantlen uint8
|
||||
- And then numframes x vecsize uint8
|
||||
|
||||
This is the format for mul (mgc and lfz) pdf files:
|
||||
- numframes: 1 uint16
|
||||
- vecsize: 1 uint8
|
||||
- numstates: 1 uint8
|
||||
- numframesperstate: numstates uint16
|
||||
- ceporder: 1 uint8
|
||||
- numvuv 1 uint8
|
||||
- numdeltas: 1 uint8
|
||||
- scmeanpow: 1 uint8
|
||||
- maxbigpow: 1 uint8
|
||||
- scmeanpowum KPDF_NUMSTREAMS * ceporder uint8
|
||||
- scivarpow KPDF_NUMSTREAMS * ceporder uint8
|
||||
|
||||
And then numframes x vecsize uint8
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* pdf data defines */
|
||||
/* may not be changed with current implementation */
|
||||
/* ************************************************************/
|
||||
|
||||
|
||||
#define KPDF_NUMSTREAMS 3 /* coeff, delta, deltadelta */
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* pdf loading */
|
||||
/* ************************************************************/
|
||||
|
||||
static pico_status_t kpdfDURInitialize(register picoknow_KnowledgeBase this,
|
||||
picoos_Common common) {
|
||||
picokpdf_pdfdur_t *pdfdur;
|
||||
picoos_uint16 pos;
|
||||
|
||||
if (NULL == this || NULL == this->subObj) {
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_KB_MISSING,
|
||||
NULL, NULL);
|
||||
}
|
||||
pdfdur = (picokpdf_pdfdur_t *)this->subObj;
|
||||
|
||||
pos = 0;
|
||||
|
||||
pdfdur->numframes = ((picoos_uint16)(this->base[pos+1])) << 8 |
|
||||
this->base[pos];
|
||||
pos += 2;
|
||||
pdfdur->vecsize = this->base[pos++];
|
||||
pdfdur->sampperframe = this->base[pos++];
|
||||
pdfdur->phonquantlen = this->base[pos++];
|
||||
pdfdur->phonquant = &(this->base[pos]);
|
||||
pos += pdfdur->phonquantlen;
|
||||
pdfdur->statequantlen = this->base[pos++];
|
||||
pdfdur->statequant = &(this->base[pos]);
|
||||
pos += pdfdur->statequantlen;
|
||||
pdfdur->content = &(this->base[pos]);
|
||||
PICODBG_DEBUG(("numframes %d, vecsize %d, phonquantlen %d, "
|
||||
"statequantlen %d", pdfdur->numframes, pdfdur->vecsize,
|
||||
pdfdur->phonquantlen, pdfdur->statequantlen));
|
||||
if ((picoos_uint32)(pos + (pdfdur->numframes * pdfdur->vecsize)) != this->size) {
|
||||
PICODBG_DEBUG(("header-spec size %d, kb-size %d",
|
||||
pos + (pdfdur->numframes * pdfdur->vecsize),
|
||||
this->size));
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_FILE_CORRUPT,
|
||||
NULL, NULL);
|
||||
}
|
||||
PICODBG_DEBUG(("dur pdf initialized"));
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
static picoos_uint8 convScaleFactorToBig(picoos_uint8 pow, picoos_uint8 bigpow)
|
||||
{
|
||||
if (pow > 0x0F) {
|
||||
pow = bigpow + (0xFF - pow + 1); /* take 2's complement of negative pow */
|
||||
} else if (bigpow >= pow) {
|
||||
pow = bigpow - pow;
|
||||
} else {
|
||||
/* error: bigpow is smaller than input pow */
|
||||
return 0;
|
||||
}
|
||||
return pow;
|
||||
}
|
||||
|
||||
static pico_status_t kpdfMULInitialize(register picoknow_KnowledgeBase this,
|
||||
picoos_Common common) {
|
||||
picokpdf_pdfmul_t *pdfmul;
|
||||
picoos_uint16 pos;
|
||||
picoos_uint8 scmeanpow, maxbigpow, nummean;
|
||||
picoos_uint8 i;
|
||||
|
||||
if (NULL == this || NULL == this->subObj) {
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_KB_MISSING,
|
||||
NULL, NULL);
|
||||
}
|
||||
pdfmul = (picokpdf_pdfmul_t *)this->subObj;
|
||||
|
||||
pos = 0;
|
||||
|
||||
pdfmul->numframes = ((picoos_uint16)(this->base[pos+1])) << 8 |
|
||||
this->base[pos];
|
||||
pos += 2;
|
||||
pdfmul->vecsize = this->base[pos++];
|
||||
pdfmul->numstates = this->base[pos++];
|
||||
{
|
||||
pdfmul->stateoffset[0] = (picoos_uint16) 0;
|
||||
for (i=1; i<pdfmul->numstates; i++) {
|
||||
pdfmul->stateoffset[i] = pdfmul->stateoffset[i-1] + (this->base[pos] | ((picoos_uint16) this->base[pos+1] << 8));
|
||||
pos += 2;
|
||||
}
|
||||
pos += 2; /* we don't need the last number if we only need the offset (i.e. how to get to the vector start) */
|
||||
}
|
||||
|
||||
pdfmul->ceporder = this->base[pos++];
|
||||
pdfmul->numvuv = this->base[pos++];
|
||||
pdfmul->numdeltas = this->base[pos++];
|
||||
scmeanpow = this->base[pos++];
|
||||
maxbigpow = this->base[pos++];
|
||||
if (maxbigpow < PICOKPDF_BIG_POW) {
|
||||
PICODBG_ERROR(("bigpow %i is larger than maxbigpow %i defined in pdf lingware", PICOKPDF_BIG_POW, maxbigpow));
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_MAX_NUM_EXCEED,NULL,NULL);
|
||||
}
|
||||
pdfmul->bigpow = PICOKPDF_BIG_POW; /* what we have to use is the smaller number! */
|
||||
|
||||
pdfmul->amplif = this->base[pos++];
|
||||
|
||||
/* bigpow corrected by scmeanpow, multiply means by 2^meanpow to obtain fixed point representation */
|
||||
pdfmul->meanpow = convScaleFactorToBig(scmeanpow, pdfmul->bigpow);
|
||||
if (0 == pdfmul->meanpow) {
|
||||
PICODBG_ERROR(("error in convScaleFactorToBig"));
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_MAX_NUM_EXCEED,NULL,NULL);
|
||||
}
|
||||
nummean = 3*pdfmul->ceporder;
|
||||
|
||||
pdfmul->meanpowUm = picoos_allocate(common->mm,nummean*sizeof(picoos_uint8));
|
||||
pdfmul->ivarpow = picoos_allocate(common->mm,nummean*sizeof(picoos_uint8));
|
||||
if ((NULL == pdfmul->meanpowUm) || (NULL == pdfmul->ivarpow)) {
|
||||
picoos_deallocate(common->mm,(void *) &(pdfmul->meanpowUm));
|
||||
picoos_deallocate(common->mm,(void *) &(pdfmul->ivarpow));
|
||||
return picoos_emRaiseException(common->em,PICO_EXC_OUT_OF_MEM,NULL,NULL);
|
||||
}
|
||||
|
||||
/* read meanpowUm and convert on the fly */
|
||||
/* meaning of meanpowUm becomes: multiply means from pdf stream by 2^meanpowUm
|
||||
* to achieve fixed point scaling by big
|
||||
*/
|
||||
for (i=0; i<nummean; i++) {
|
||||
pdfmul->meanpowUm[i] = convScaleFactorToBig(this->base[pos++], pdfmul->bigpow);
|
||||
}
|
||||
|
||||
/*read ivarpow and convert on the fly */
|
||||
for (i=0; i<nummean; i++) {
|
||||
pdfmul->ivarpow[i] = convScaleFactorToBig(this->base[pos++], pdfmul->bigpow);
|
||||
}
|
||||
|
||||
/* check numdeltas */
|
||||
if ((pdfmul->numdeltas == 0xFF) && (pdfmul->vecsize != (pdfmul->numvuv + pdfmul->ceporder * 3 * (2+1)))) {
|
||||
PICODBG_ERROR(("header has inconsistent values for vecsize, ceporder, numvuv, and numdeltas"));
|
||||
return picoos_emRaiseException(common->em,PICO_EXC_FILE_CORRUPT,NULL,NULL);
|
||||
}
|
||||
|
||||
/* vecsize: 1 uint8 for vuv
|
||||
+ ceporder short for static means
|
||||
+ numdeltas uint8 and short for sparse delta means
|
||||
+ ceporder*3 uint8 for static and delta inverse variances
|
||||
*/
|
||||
if ((pdfmul->numdeltas != 0xFF) && (pdfmul->vecsize != pdfmul->numvuv+pdfmul->ceporder*2+pdfmul->numdeltas*3+pdfmul->ceporder*3)) {
|
||||
PICODBG_ERROR(("header has inconsistent values for vecsize, ceporder, numvuv, and numdeltas\n"
|
||||
"vecsize = %i while numvuv+ceporder*2 + numdeltas*3 + ceporder*3 = %i",
|
||||
pdfmul->vecsize, pdfmul->numvuv + pdfmul->ceporder*2 + pdfmul->numdeltas * 3 + pdfmul->ceporder * 3));
|
||||
return picoos_emRaiseException(common->em,PICO_EXC_FILE_CORRUPT,NULL,NULL);
|
||||
}
|
||||
pdfmul->content = &(this->base[pos]);
|
||||
PICODBG_DEBUG(("numframes %d, vecsize %d, numstates %d, ceporder %d, "
|
||||
"numvuv %d, numdeltas %d, meanpow %d, bigpow %d",
|
||||
pdfmul->numframes, pdfmul->vecsize, pdfmul->numstates,
|
||||
pdfmul->ceporder, pdfmul->numvuv, pdfmul->numdeltas,
|
||||
pdfmul->meanpow, pdfmul->bigpow));
|
||||
if ((picoos_uint32)(pos + (pdfmul->numframes * pdfmul->vecsize)) != this->size) {
|
||||
PICODBG_DEBUG(("header-spec size %d, kb-size %d",
|
||||
pos + (pdfmul->numframes * pdfmul->vecsize),
|
||||
this->size));
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_FILE_CORRUPT,
|
||||
NULL, NULL);
|
||||
}
|
||||
PICODBG_DEBUG(("mul pdf initialized"));
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
static pico_status_t kpdfPHSInitialize(register picoknow_KnowledgeBase this,
|
||||
picoos_Common common) {
|
||||
picokpdf_pdfphs_t *pdfphs;
|
||||
picoos_uint16 pos;
|
||||
|
||||
if (NULL == this || NULL == this->subObj) {
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_KB_MISSING,
|
||||
NULL, NULL);
|
||||
}
|
||||
pdfphs = (picokpdf_pdfphs_t *)this->subObj;
|
||||
|
||||
pos = 0;
|
||||
|
||||
pdfphs->numvectors = ((picoos_uint16)(this->base[pos+1])) << 8 |
|
||||
this->base[pos];
|
||||
pos += 2;
|
||||
pdfphs->indexBase = &(this->base[pos]);
|
||||
pdfphs->contentBase = pdfphs->indexBase + pdfphs->numvectors * sizeof(picoos_uint32);
|
||||
PICODBG_DEBUG(("phs pdf initialized"));
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static pico_status_t kpdfMULSubObjDeallocate(register picoknow_KnowledgeBase this,
|
||||
picoos_MemoryManager mm) {
|
||||
|
||||
|
||||
picokpdf_pdfmul_t *pdfmul;
|
||||
|
||||
if ((NULL != this) && (NULL != this->subObj)) {
|
||||
pdfmul = (picokpdf_pdfmul_t *)this->subObj;
|
||||
picoos_deallocate(mm,(void *) &(pdfmul->meanpowUm));
|
||||
picoos_deallocate(mm,(void *) &(pdfmul->ivarpow));
|
||||
picoos_deallocate(mm, (void *) &(this->subObj));
|
||||
}
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
static pico_status_t kpdfDURSubObjDeallocate(register picoknow_KnowledgeBase this,
|
||||
picoos_MemoryManager mm) {
|
||||
if (NULL != this) {
|
||||
picoos_deallocate(mm, (void *) &this->subObj);
|
||||
}
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
static pico_status_t kpdfPHSSubObjDeallocate(register picoknow_KnowledgeBase this,
|
||||
picoos_MemoryManager mm) {
|
||||
if (NULL != this) {
|
||||
picoos_deallocate(mm, (void *) &this->subObj);
|
||||
}
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
/* we don't offer a specialized constructor for a *KnowledgeBase but
|
||||
* instead a "specializer" of an allready existing generic
|
||||
* picoknow_KnowledgeBase */
|
||||
|
||||
pico_status_t picokpdf_specializePdfKnowledgeBase(picoknow_KnowledgeBase this,
|
||||
picoos_Common common,
|
||||
const picokpdf_kpdftype_t kpdftype) {
|
||||
pico_status_t status;
|
||||
|
||||
if (NULL == this) {
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_KB_MISSING,
|
||||
NULL, NULL);
|
||||
}
|
||||
switch (kpdftype) {
|
||||
case PICOKPDF_KPDFTYPE_DUR:
|
||||
this->subDeallocate = kpdfDURSubObjDeallocate;
|
||||
this->subObj = picoos_allocate(common->mm,sizeof(picokpdf_pdfdur_t));
|
||||
if (NULL == this->subObj) {
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_OUT_OF_MEM,
|
||||
NULL, NULL);
|
||||
}
|
||||
status = kpdfDURInitialize(this, common);
|
||||
break;
|
||||
case PICOKPDF_KPDFTYPE_MUL:
|
||||
this->subDeallocate = kpdfMULSubObjDeallocate;
|
||||
this->subObj = picoos_allocate(common->mm,sizeof(picokpdf_pdfmul_t));
|
||||
if (NULL == this->subObj) {
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_OUT_OF_MEM,
|
||||
NULL, NULL);
|
||||
}
|
||||
status = kpdfMULInitialize(this, common);
|
||||
break;
|
||||
case PICOKPDF_KPDFTYPE_PHS:
|
||||
this->subDeallocate = kpdfPHSSubObjDeallocate;
|
||||
this->subObj = picoos_allocate(common->mm,sizeof(picokpdf_pdfphs_t));
|
||||
if (NULL == this->subObj) {
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_OUT_OF_MEM,
|
||||
NULL, NULL);
|
||||
}
|
||||
status = kpdfPHSInitialize(this, common);
|
||||
break;
|
||||
|
||||
default:
|
||||
return picoos_emRaiseException(common->em, PICO_ERR_OTHER,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
if (status != PICO_OK) {
|
||||
picoos_deallocate(common->mm, (void *) &this->subObj);
|
||||
return picoos_emRaiseException(common->em, status, NULL, NULL);
|
||||
}
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* pdf getPdf* */
|
||||
/* ************************************************************/
|
||||
|
||||
picokpdf_PdfDUR picokpdf_getPdfDUR(picoknow_KnowledgeBase this) {
|
||||
return ((NULL == this) ? NULL : ((picokpdf_PdfDUR) this->subObj));
|
||||
}
|
||||
|
||||
picokpdf_PdfMUL picokpdf_getPdfMUL(picoknow_KnowledgeBase this) {
|
||||
return ((NULL == this) ? NULL : ((picokpdf_PdfMUL) this->subObj));
|
||||
}
|
||||
|
||||
picokpdf_PdfPHS picokpdf_getPdfPHS(picoknow_KnowledgeBase this) {
|
||||
return ((NULL == this) ? NULL : ((picokpdf_PdfPHS) this->subObj));
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* end */
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picokpdf.h
|
||||
*
|
||||
* knowledge handling for pdf
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PICOKPDF_H_
|
||||
#define PICOKPDF_H_
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picoknow.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/**
|
||||
* @addtogroup picokpdf
|
||||
*
|
||||
Two specialized pdf kb types are provided by this knowledge
|
||||
handling module:
|
||||
|
||||
- pdf dur: ...kpdf_DUR (for dur)
|
||||
- pdf mul: ...kpdf_MUL (for lfz and mgc)
|
||||
- pdf phs: ...kpdf_PHS (for phase)
|
||||
|
||||
*/
|
||||
/* ************************************************************/
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* defines and functions to create specialized kb, */
|
||||
/* to be used by picorsrc only */
|
||||
/* ************************************************************/
|
||||
|
||||
#define PICOKPDF_MAX_NUM_STATES 10
|
||||
|
||||
#define PICOKPDF_MAX_MUL_LFZ_CEPORDER 1
|
||||
#define PICOKPDF_MAX_MUL_MGC_CEPORDER 25
|
||||
|
||||
/* trade accuracy against computation: more long multiplications.
|
||||
* Maximum is 15 when invdiag0=(1<<(2*bigpow))/diag0 used
|
||||
* currently observing instability in mlpg when bigpow >= 14, this needs to be investigated */
|
||||
|
||||
#define PICOKPDF_BIG_POW 12
|
||||
|
||||
typedef enum {
|
||||
PICOKPDF_KPDFTYPE_DUR,
|
||||
PICOKPDF_KPDFTYPE_MUL,
|
||||
PICOKPDF_KPDFTYPE_PHS
|
||||
} picokpdf_kpdftype_t;
|
||||
|
||||
pico_status_t picokpdf_specializePdfKnowledgeBase(picoknow_KnowledgeBase this,
|
||||
picoos_Common common,
|
||||
const picokpdf_kpdftype_t type);
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* pdf types and get Pdf functions */
|
||||
/* ************************************************************/
|
||||
|
||||
/** object : PdfDur, PdfMUL
|
||||
* shortcut : kpdf*
|
||||
* derived from : picoknow_KnowledgeBase
|
||||
*/
|
||||
|
||||
typedef struct picokpdf_pdfdur *picokpdf_PdfDUR;
|
||||
typedef struct picokpdf_pdfmul *picokpdf_PdfMUL;
|
||||
typedef struct picokpdf_pdfphs *picokpdf_PdfPHS;
|
||||
|
||||
/* subobj specific for pdf dur type */
|
||||
typedef struct picokpdf_pdfdur {
|
||||
picoos_uint16 numframes;
|
||||
picoos_uint8 vecsize;
|
||||
picoos_uint8 sampperframe;
|
||||
picoos_uint8 phonquantlen;
|
||||
picoos_uint8 *phonquant;
|
||||
picoos_uint8 statequantlen;
|
||||
picoos_uint8 *statequant;
|
||||
picoos_uint8 *content;
|
||||
} picokpdf_pdfdur_t;
|
||||
|
||||
/* subobj specific for pdf mul type */
|
||||
typedef struct picokpdf_pdfmul {
|
||||
picoos_uint16 numframes;
|
||||
picoos_uint8 vecsize;
|
||||
picoos_uint8 numstates;
|
||||
picoos_uint16 stateoffset[PICOKPDF_MAX_NUM_STATES]; /* offset within a phone to find the state ? */
|
||||
picoos_uint8 ceporder;
|
||||
picoos_uint8 numvuv;
|
||||
picoos_uint8 numdeltas;
|
||||
picoos_uint8 meanpow;
|
||||
picoos_uint8 bigpow;
|
||||
picoos_uint8 amplif;
|
||||
picoos_uint8 *meanpowUm; /* KPDF_NUMSTREAMS x ceporder values */
|
||||
picoos_uint8 *ivarpow; /* KPDF_NUMSTREAMS x ceporder values */
|
||||
picoos_uint8 *content;
|
||||
} picokpdf_pdfmul_t;
|
||||
|
||||
/* subobj specific for pdf phs type */
|
||||
typedef struct picokpdf_pdfphs {
|
||||
picoos_uint16 numvectors;
|
||||
picoos_uint8 *indexBase;
|
||||
picoos_uint8 *contentBase;
|
||||
} picokpdf_pdfphs_t;
|
||||
|
||||
/* return kb pdf for usage in PU */
|
||||
picokpdf_PdfDUR picokpdf_getPdfDUR(picoknow_KnowledgeBase this);
|
||||
picokpdf_PdfMUL picokpdf_getPdfMUL(picoknow_KnowledgeBase this);
|
||||
picokpdf_PdfPHS picokpdf_getPdfPHS(picoknow_KnowledgeBase this);
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* PDF DUR functions */
|
||||
/* ************************************************************/
|
||||
|
||||
/* e.g. */
|
||||
/*picoos_uint8 picokpdf_pdfDURgetEle(const picokpdf_PdfDUR this,
|
||||
const picoos_uint16 row,
|
||||
const picoos_uint16 col,
|
||||
picoos_uint16 *val);
|
||||
*/
|
||||
|
||||
/* ************************************************************/
|
||||
/* PDF MUL functions */
|
||||
/* ************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*PICOKPDF_H_*/
|
||||
@@ -0,0 +1,652 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picokpr.c
|
||||
*
|
||||
* knowledge handling for text preprocessing
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
#include "picoos.h"
|
||||
#include "picodbg.h"
|
||||
#include "picodata.h"
|
||||
#include "picoknow.h"
|
||||
#include "picokpr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* preproc */
|
||||
/* ************************************************************/
|
||||
|
||||
/*
|
||||
overview:
|
||||
*/
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* preproc data defines */
|
||||
/* ************************************************************/
|
||||
|
||||
#define KPR_STR_SIZE 1
|
||||
#define KPR_LEXCAT_SIZE 2
|
||||
#define KPR_ATTRVAL_SIZE 4
|
||||
#define KPR_OUTITEM_SIZE 7
|
||||
#define KPR_TOK_SIZE 16
|
||||
#define KPR_PROD_SIZE 12
|
||||
#define KPR_CTX_SIZE 12
|
||||
|
||||
#define KPR_NETNAME_OFFSET 0
|
||||
#define KPR_STRARRLEN_OFFSET 4
|
||||
#define KPR_LEXCATARRLEN_OFFSET 8
|
||||
#define KPR_ATTRVALARRLEN_OFFSET 12
|
||||
#define KPR_OUTITEMARRLEN_OFFSET 16
|
||||
#define KPR_TOKARRLEN_OFFSET 20
|
||||
#define KPR_PRODARRLEN_OFFSET 24
|
||||
#define KPR_CTXARRLEN_OFFSET 28
|
||||
|
||||
#define KPR_ARRAY_START 32
|
||||
|
||||
#define KPR_MAX_INT32 2147483647
|
||||
|
||||
#define KPR_STR_OFS 0
|
||||
|
||||
#define KPR_LEXCAT_OFS 0
|
||||
|
||||
#define KPR_ATTRVAL_INT_OFS 0
|
||||
#define KPR_ATTRVAL_STROFS_OFS 0
|
||||
#define KPR_ATTRVAL_PRODOFS_OFS 0
|
||||
#define KPR_ATTRVAL_OUTITMOFS_OFS 0
|
||||
#define KPR_ATTRVAL_LEXCATOFS_OFS 0
|
||||
|
||||
#define KPR_OUTITEM_NEXTOFS_OFS 0
|
||||
#define KPR_OUTITEM_TYPE_OFS 2
|
||||
#define KPR_OUTITEM_STROFS_OFS 3
|
||||
#define KPR_OUTITEM_VAL_OFS 3
|
||||
#define KPR_OUTITEM_ARGOFS_OFS 3
|
||||
|
||||
#define KPR_TOK_SETWP_OFS 0
|
||||
#define KPR_TOK_SETNP_OFS 4
|
||||
#define KPR_TOK_NEXTOFS_OFS 8
|
||||
#define KPR_TOK_ALTLOFS_OFS 10
|
||||
#define KPR_TOK_ALTROFS_OFS 12
|
||||
#define KPR_TOK_ATTRIBOFS_OFS 14
|
||||
|
||||
#define KPR_PROD_PRODPREFCOST_OFS 0
|
||||
#define KPR_PROD_PRODNAMEOFS_OFS 4
|
||||
#define KPR_PROD_ATOKOFS_OFS 8
|
||||
#define KPR_PROD_ETOKOFS_OFS 10
|
||||
|
||||
#define KPR_CTX_CTXNAMEOFS_OFS 0
|
||||
#define KPR_CTX_NETNAMEOFS_OFS 4
|
||||
#define KPR_CTX_PRODNAMEOFS_OFS 8
|
||||
|
||||
/* ************************************************************/
|
||||
/* preproc type and loading */
|
||||
/* ************************************************************/
|
||||
|
||||
/* variable array element types */
|
||||
typedef picoos_uint8 picokpr_Str[KPR_STR_SIZE];
|
||||
typedef picoos_uint16 picokpr_LexCat2;
|
||||
typedef picoos_uint8 picokpr_AttrVal[KPR_ATTRVAL_SIZE];
|
||||
typedef picoos_uint8 picokpr_OutItem[KPR_OUTITEM_SIZE];
|
||||
typedef picoos_uint8 picokpr_Tok[KPR_TOK_SIZE];
|
||||
typedef picoos_uint8 picokpr_Prod[KPR_PROD_SIZE];
|
||||
typedef picoos_uint8 picokpr_Ctx[KPR_CTX_SIZE];
|
||||
|
||||
/* variable array types */
|
||||
typedef picokpr_Str * picokpr_VarStrArr;
|
||||
typedef picokpr_LexCat2 * picokpr_VarLexCatArr;
|
||||
typedef picokpr_AttrVal * picokpr_VarAttrValArr;
|
||||
typedef picokpr_OutItem * picokpr_VarOutItemArr;
|
||||
typedef picokpr_Tok * picokpr_VarTokArr;
|
||||
typedef picokpr_Prod * picokpr_VarProdArr;
|
||||
typedef picokpr_Ctx * picokpr_VarCtxArr;
|
||||
|
||||
/* ************************************************************/
|
||||
/* preproc type and loading */
|
||||
/* ************************************************************/
|
||||
|
||||
/** object : PreprocKnowledgeBase
|
||||
* shortcut : kpr
|
||||
* derived from : picoknow_KnowledgeBase
|
||||
*/
|
||||
|
||||
typedef struct kpr_subobj * kpr_SubObj;
|
||||
|
||||
typedef struct kpr_subobj
|
||||
{
|
||||
picoos_uchar * rNetName;
|
||||
|
||||
picoos_int32 rStrArrLen;
|
||||
picoos_int32 rLexCatArrLen;
|
||||
picoos_int32 rAttrValArrLen;
|
||||
picoos_int32 rOutItemArrLen;
|
||||
picoos_int32 rTokArrLen;
|
||||
picoos_int32 rProdArrLen;
|
||||
picoos_int32 rCtxArrLen;
|
||||
|
||||
picoos_uint8 * rStrArr;
|
||||
picokpr_LexCat2 * rLexCatArr;
|
||||
picokpr_AttrVal * rAttrValArr;
|
||||
picokpr_OutItem * rOutItemArr;
|
||||
picokpr_Tok * rTokArr;
|
||||
picokpr_Prod * rProdArr;
|
||||
picokpr_Ctx * rCtxArr;
|
||||
} kpr_subobj_t;
|
||||
|
||||
|
||||
static picoos_uint32 kpr_getUInt32(picoos_uint8 * p)
|
||||
{
|
||||
return p[0] + 256*p[1] + 256*256*p[2] + 256U*256U*256U*p[3];
|
||||
}
|
||||
|
||||
|
||||
static pico_status_t kprInitialize(register picoknow_KnowledgeBase this,
|
||||
picoos_Common common)
|
||||
{
|
||||
picoos_uint32 offset = 0;
|
||||
kpr_subobj_t * kpr;
|
||||
|
||||
PICODBG_DEBUG(("start"));
|
||||
|
||||
if (NULL == this || NULL == this->subObj) {
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_KB_MISSING,
|
||||
NULL, NULL);
|
||||
}
|
||||
kpr = (kpr_subobj_t *) this->subObj;
|
||||
|
||||
kpr->rStrArrLen = kpr_getUInt32(&(this->base[KPR_STRARRLEN_OFFSET]));
|
||||
kpr->rLexCatArrLen = kpr_getUInt32(&(this->base[KPR_LEXCATARRLEN_OFFSET]));
|
||||
kpr->rAttrValArrLen = kpr_getUInt32(&(this->base[KPR_ATTRVALARRLEN_OFFSET]));
|
||||
kpr->rOutItemArrLen = kpr_getUInt32(&(this->base[KPR_OUTITEMARRLEN_OFFSET]));
|
||||
kpr->rTokArrLen = kpr_getUInt32(&(this->base[KPR_TOKARRLEN_OFFSET]));
|
||||
kpr->rProdArrLen = kpr_getUInt32(&(this->base[KPR_PRODARRLEN_OFFSET]));
|
||||
kpr->rCtxArrLen = kpr_getUInt32(&(this->base[KPR_CTXARRLEN_OFFSET]));
|
||||
|
||||
offset = KPR_ARRAY_START;
|
||||
kpr->rStrArr = &(this->base[offset]);
|
||||
PICODBG_DEBUG(("rStrArr : cs: %i, ss: %i, offset: %i", sizeof(picokpr_Str), KPR_STR_SIZE, offset));
|
||||
offset = offset + kpr->rStrArrLen * 1;
|
||||
|
||||
kpr->rLexCatArr = (picokpr_LexCat2 *)&(this->base[offset]);
|
||||
PICODBG_DEBUG(("rLexCatArr : cs: %i, ss: %i, offset: %i", KPR_LEXCAT_SIZE, sizeof(picokpr_LexCat2), offset));
|
||||
offset = offset + kpr->rLexCatArrLen * KPR_LEXCAT_SIZE;
|
||||
|
||||
kpr->rAttrValArr = (picokpr_AttrVal *)&(this->base[offset]);
|
||||
PICODBG_DEBUG(("rAttrValArr : cs: %i, ss: %i, offset: %i", KPR_ATTRVAL_SIZE, sizeof(picokpr_AttrVal), offset));
|
||||
offset = offset + kpr->rAttrValArrLen * KPR_ATTRVAL_SIZE;
|
||||
|
||||
kpr->rOutItemArr = (picokpr_OutItem *)&(this->base[offset]);
|
||||
PICODBG_DEBUG(("rOutItemArr : cs: %i, ss: %i, offset: %i", KPR_OUTITEM_SIZE, sizeof(picokpr_OutItem), offset));
|
||||
offset = offset + kpr->rOutItemArrLen * KPR_OUTITEM_SIZE;
|
||||
|
||||
kpr->rTokArr = (picokpr_Tok *)&(this->base[offset]);
|
||||
PICODBG_DEBUG(("rTokArr : cs: %i, ss: %i, offset: %i", KPR_TOK_SIZE, sizeof(picokpr_Tok), offset));
|
||||
offset = offset + kpr->rTokArrLen * KPR_TOK_SIZE;
|
||||
|
||||
kpr->rProdArr = (picokpr_Prod *)&(this->base[offset]);
|
||||
PICODBG_DEBUG(("rProdArr : cs: %i, ss: %i, offset: %i", KPR_PROD_SIZE, sizeof(picokpr_Prod), offset));
|
||||
offset = offset + kpr->rProdArrLen * KPR_PROD_SIZE;
|
||||
|
||||
kpr->rCtxArr = (picokpr_Ctx *)&(this->base[offset]);
|
||||
PICODBG_DEBUG(("rCtxArr : cs: %i, ss: %i, offset: %i", KPR_CTX_SIZE, sizeof(picokpr_Ctx), offset));
|
||||
offset = offset + kpr->rCtxArrLen * KPR_CTX_SIZE;
|
||||
|
||||
kpr->rNetName = &(kpr->rStrArr[kpr_getUInt32(&(this->base[KPR_NETNAME_OFFSET]))]);
|
||||
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
static pico_status_t kprSubObjDeallocate(register picoknow_KnowledgeBase this,
|
||||
picoos_MemoryManager mm)
|
||||
{
|
||||
if (NULL != this) {
|
||||
picoos_deallocate(mm, (void *) &this->subObj);
|
||||
}
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
/* we don't offer a specialized constructor for a PreprocKnowledgeBase but
|
||||
* instead a "specializer" of an allready existing generic
|
||||
* picoknow_KnowledgeBase */
|
||||
|
||||
pico_status_t picokpr_specializePreprocKnowledgeBase(picoknow_KnowledgeBase this,
|
||||
picoos_Common common)
|
||||
{
|
||||
if (NULL == this) {
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_KB_MISSING,
|
||||
NULL, NULL);
|
||||
}
|
||||
this->subDeallocate = kprSubObjDeallocate;
|
||||
this->subObj = picoos_allocate(common->mm, sizeof(kpr_subobj_t));
|
||||
if (NULL == this->subObj) {
|
||||
return picoos_emRaiseException(common->em, PICO_EXC_OUT_OF_MEM,
|
||||
NULL, NULL);
|
||||
}
|
||||
return kprInitialize(this, common);
|
||||
}
|
||||
|
||||
/* ************************************************************/
|
||||
/* preproc getPreproc */
|
||||
/* ************************************************************/
|
||||
|
||||
picokpr_Preproc picokpr_getPreproc(picoknow_KnowledgeBase this)
|
||||
{
|
||||
if (NULL == this) {
|
||||
return NULL;
|
||||
} else {
|
||||
return (picokpr_Preproc) this->subObj;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* *****************************************************************************/
|
||||
/* knowledge base access routines for strings in StrArr */
|
||||
/* *****************************************************************************/
|
||||
|
||||
extern picokpr_VarStrPtr picokpr_getVarStrPtr(picokpr_Preproc preproc, picokpr_StrArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rStrArr[ofs]);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* *****************************************************************************/
|
||||
|
||||
extern picoos_bool picokpr_isEqual (picokpr_Preproc preproc, picoos_uchar str[], picoos_int32 len__9, picokpr_StrArrOffset str2)
|
||||
{
|
||||
picokpr_VarStrPtr lstrp;
|
||||
len__9 = len__9; /*PP 13.10.08 : fix warning "var not used in this function"*/
|
||||
lstrp = (picokpr_VarStrPtr)&((kpr_SubObj)preproc)->rStrArr[str2];
|
||||
return picoos_strcmp((picoos_char*)lstrp,(picoos_char*)str) == 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern picoos_bool picokpr_isEqualHead (picokpr_Preproc preproc, picoos_uchar str[], picoos_int32 len__10, picokpr_StrArrOffset head)
|
||||
{
|
||||
picokpr_VarStrPtr lstrp;
|
||||
len__10 = len__10; /*PP 13.10.08 : fix warning "var not used in this function"*/
|
||||
lstrp = (picokpr_VarStrPtr)&((kpr_SubObj)preproc)->rStrArr[head];
|
||||
return (picoos_strstr((picoos_char*)str, (picoos_char*)lstrp) == (picoos_char*)str);
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern picoos_bool picokpr_isEqualMid (picokpr_Preproc preproc, picoos_uchar str[], picoos_int32 len__11, picokpr_StrArrOffset mid)
|
||||
{
|
||||
picokpr_VarStrPtr lstrp;
|
||||
len__11 = len__11; /*PP 13.10.08 : fix warning "var not used in this function"*/
|
||||
lstrp = (picokpr_VarStrPtr)(void *) &((kpr_SubObj)preproc)->rStrArr[mid];
|
||||
return (picoos_strstr((picoos_char*)str, (picoos_char*)lstrp) != NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern picoos_bool picokpr_isEqualTail (picokpr_Preproc preproc, picoos_uchar str[], picoos_int32 len__12, picokpr_StrArrOffset tail)
|
||||
{
|
||||
picoos_int32 lstart;
|
||||
picokpr_VarStrPtr lstrp;
|
||||
len__12 = len__12; /* avoid warning "var not used in this function"*/
|
||||
lstrp = (picokpr_VarStrPtr)&((kpr_SubObj)preproc)->rStrArr[tail];
|
||||
lstart = picoos_strlen((picoos_char*)str) - picoos_strlen((picoos_char*)lstrp);
|
||||
if (lstart >= 0) {
|
||||
return (picoos_strstr((picoos_char*)&(str[lstart]), (picoos_char*)lstrp) != NULL);
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* *****************************************************************************/
|
||||
/* knowledge base access routines for lexical categories in LexCatArr */
|
||||
/* *****************************************************************************/
|
||||
|
||||
extern picokpr_LexCat picokpr_getLexCat(picokpr_Preproc preproc, picokpr_LexCatArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rLexCatArr[ofs]);
|
||||
|
||||
return p[0] + 256*p[1];
|
||||
}
|
||||
|
||||
/* *****************************************************************************/
|
||||
/* knowledge base access routines for AttrVal fields in AttrValArr */
|
||||
/* *****************************************************************************/
|
||||
|
||||
extern picoos_int32 picokpr_getAttrValArrInt32(picokpr_Preproc preproc, picokpr_AttrValArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rAttrValArr[ofs]);
|
||||
picoos_uint32 c = p[KPR_ATTRVAL_INT_OFS] +
|
||||
256*p[KPR_ATTRVAL_INT_OFS+1] +
|
||||
256*256*p[KPR_ATTRVAL_INT_OFS+2] +
|
||||
256U*256U*256U*p[KPR_ATTRVAL_INT_OFS+3];
|
||||
|
||||
if (c > KPR_MAX_INT32) {
|
||||
return (c - KPR_MAX_INT32) - 1;
|
||||
} else {
|
||||
return (((int)c + (int) -(KPR_MAX_INT32)) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* *****************************************************************************/
|
||||
/* knowledge base access routines for AttrVal fields in AttrValArr */
|
||||
/* *****************************************************************************/
|
||||
|
||||
extern picokpr_OutItemArrOffset picokpr_getOutItemNextOfs(picokpr_Preproc preproc, picokpr_OutItemArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rOutItemArr[ofs]);
|
||||
|
||||
return p[KPR_OUTITEM_NEXTOFS_OFS+0] + 256*p[KPR_OUTITEM_NEXTOFS_OFS+1];
|
||||
}
|
||||
|
||||
|
||||
extern picoos_int32 picokpr_getOutItemType(picokpr_Preproc preproc, picokpr_OutItemArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rOutItemArr[ofs]);
|
||||
|
||||
return p[KPR_OUTITEM_TYPE_OFS+0];
|
||||
}
|
||||
|
||||
|
||||
extern picokpr_StrArrOffset picokpr_getOutItemStrOfs(picokpr_Preproc preproc, picokpr_OutItemArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rOutItemArr[ofs]);
|
||||
|
||||
return p[KPR_OUTITEM_STROFS_OFS+0] +
|
||||
256*p[KPR_OUTITEM_STROFS_OFS+1] +
|
||||
256*256*p[KPR_OUTITEM_STROFS_OFS+2] +
|
||||
256U*256U*256U*p[KPR_OUTITEM_STROFS_OFS+3];
|
||||
}
|
||||
|
||||
|
||||
extern picokpr_VarStrPtr picokpr_getOutItemStr(picokpr_Preproc preproc, picokpr_OutItemArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rOutItemArr[ofs]);
|
||||
picoos_uint32 c = p[KPR_OUTITEM_STROFS_OFS+0] +
|
||||
256*p[KPR_OUTITEM_STROFS_OFS+1] +
|
||||
256*256*p[KPR_OUTITEM_STROFS_OFS+2] +
|
||||
256U*256U*256U*p[KPR_OUTITEM_STROFS_OFS+3];
|
||||
|
||||
return (picoos_uint8 *)&(((kpr_SubObj)preproc)->rStrArr[c]);
|
||||
}
|
||||
|
||||
extern picoos_int32 picokpr_getOutItemVal(picokpr_Preproc preproc, picokpr_OutItemArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rOutItemArr[ofs]);
|
||||
picoos_uint32 c = p[KPR_OUTITEM_VAL_OFS+0] +
|
||||
256*p[KPR_OUTITEM_VAL_OFS+1] +
|
||||
256*256*p[KPR_OUTITEM_VAL_OFS+2] +
|
||||
256U*256U*256U*p[KPR_OUTITEM_VAL_OFS+3];
|
||||
|
||||
if (c > KPR_MAX_INT32) {
|
||||
return (c - KPR_MAX_INT32) - 1;
|
||||
} else {
|
||||
return (((int)c + (int) -(KPR_MAX_INT32)) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern picokpr_OutItemArrOffset picokpr_getOutItemArgOfs(picokpr_Preproc preproc, picokpr_OutItemArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rOutItemArr[ofs]);
|
||||
|
||||
return p[KPR_OUTITEM_ARGOFS_OFS+0] +
|
||||
256*p[KPR_OUTITEM_ARGOFS_OFS+1] +
|
||||
256*256*p[KPR_OUTITEM_ARGOFS_OFS+2] +
|
||||
256U*256U*256U*p[KPR_OUTITEM_ARGOFS_OFS+3];
|
||||
}
|
||||
|
||||
|
||||
/* *****************************************************************************/
|
||||
/* knowledge base access routines for tokens in TokArr */
|
||||
/* *****************************************************************************/
|
||||
|
||||
extern picokpr_TokSetNP picokpr_getTokSetNP(picokpr_Preproc preproc, picokpr_TokArrOffset ofs)
|
||||
{
|
||||
picoos_uint32 c/*, b*/;
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rTokArr[ofs]) + KPR_TOK_SETNP_OFS;
|
||||
/*picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rTokArr[ofs]);*/
|
||||
picoos_uint32 p0, p1, p2, p3;
|
||||
|
||||
p0 = *(p++);
|
||||
p1 = *(p++);
|
||||
p2 = *(p++);
|
||||
p3 = *p;
|
||||
|
||||
c = p0 + (p1<<8) + (p2<<16) + (p3<<24);
|
||||
|
||||
return c;
|
||||
|
||||
/*
|
||||
c = p[KPR_TOK_SETNP_OFS+0] +
|
||||
256*p[KPR_TOK_SETNP_OFS+1] +
|
||||
256*256*p[KPR_TOK_SETNP_OFS+2] +
|
||||
256U*256U*256U*p[KPR_TOK_SETNP_OFS+3];
|
||||
|
||||
b = 0;
|
||||
i = 0;
|
||||
while ((i <= 31) && (c > 0)) {
|
||||
if (c % 2 == 1) {
|
||||
b |= (1<<i);
|
||||
}
|
||||
c = c / 2;
|
||||
i++;
|
||||
}
|
||||
|
||||
return b;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
extern picokpr_TokSetWP picokpr_getTokSetWP(picokpr_Preproc preproc, picokpr_TokArrOffset ofs)
|
||||
{
|
||||
picoos_uint32 c/*, b*/;
|
||||
/* picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rTokArr[ofs]);*/
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rTokArr[ofs]) + KPR_TOK_SETWP_OFS;
|
||||
picoos_uint32 p0, p1, p2, p3;
|
||||
|
||||
p0 = *(p++);
|
||||
p1 = *(p++);
|
||||
p2 = *(p++);
|
||||
p3 = *p;
|
||||
|
||||
c = p0 + (p1<<8) + (p2<<16) + (p3<<24);
|
||||
return c;
|
||||
|
||||
/*
|
||||
c = p[KPR_TOK_SETWP_OFS+0] +
|
||||
256*p[KPR_TOK_SETWP_OFS+1] +
|
||||
256*256*p[KPR_TOK_SETWP_OFS+2] +
|
||||
256U*256U*256U*p[KPR_TOK_SETWP_OFS+3];
|
||||
|
||||
b = 0;
|
||||
i = 0;
|
||||
while ((i <= 31) && (c > 0)) {
|
||||
if (c % 2 == 1) {
|
||||
b |= (1<<i);
|
||||
}
|
||||
c = c / 2;
|
||||
i++;
|
||||
}
|
||||
|
||||
return b;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
extern picokpr_TokArrOffset picokpr_getTokNextOfs(picokpr_Preproc preproc, picokpr_TokArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rTokArr[ofs]);
|
||||
|
||||
return p[KPR_TOK_NEXTOFS_OFS+0] + 256*p[KPR_TOK_NEXTOFS_OFS+1];
|
||||
}
|
||||
|
||||
|
||||
extern picokpr_TokArrOffset picokpr_getTokAltLOfs(picokpr_Preproc preproc, picokpr_TokArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rTokArr[ofs]) + KPR_TOK_ALTLOFS_OFS;
|
||||
picokpr_TokArrOffset c = *p++;
|
||||
return c + 256**p;
|
||||
|
||||
/*picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rTokArr[ofs]);
|
||||
|
||||
return p[KPR_TOK_ALTLOFS_OFS+0] + 256*p[KPR_TOK_ALTLOFS_OFS+1];
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
extern picokpr_TokArrOffset picokpr_getTokAltROfs(picokpr_Preproc preproc, picokpr_TokArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rTokArr[ofs]) + KPR_TOK_ALTROFS_OFS;
|
||||
picokpr_TokArrOffset c = *p++;
|
||||
return c + 256**p;
|
||||
|
||||
/*picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rTokArr[ofs]);
|
||||
|
||||
return p[KPR_TOK_ALTROFS_OFS+0] + 256*p[KPR_TOK_ALTROFS_OFS+1];*/
|
||||
}
|
||||
|
||||
|
||||
extern picokpr_AttrValArrOffset picokpr_getTokAttribOfs(picokpr_Preproc preproc, picokpr_TokArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rTokArr[ofs]);
|
||||
|
||||
return p[KPR_TOK_ATTRIBOFS_OFS+0] + 256*p[KPR_TOK_ATTRIBOFS_OFS+1];
|
||||
}
|
||||
|
||||
/* *****************************************************************************/
|
||||
/* knowledge base access routines for productions in ProdArr */
|
||||
/* *****************************************************************************/
|
||||
|
||||
extern picoos_int32 picokpr_getProdArrLen(picokpr_Preproc preproc)
|
||||
{
|
||||
return ((kpr_SubObj)preproc)->rProdArrLen;
|
||||
}
|
||||
|
||||
extern picoos_int32 picokpr_getProdPrefCost(picokpr_Preproc preproc, picokpr_ProdArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rProdArr[ofs]);
|
||||
picoos_uint32 c = p[KPR_PROD_PRODPREFCOST_OFS+0] +
|
||||
256*p[KPR_PROD_PRODPREFCOST_OFS+1] +
|
||||
256*256*p[KPR_PROD_PRODPREFCOST_OFS+2] +
|
||||
256U*256U*256U*p[KPR_PROD_PRODPREFCOST_OFS+3];
|
||||
|
||||
|
||||
if (c > KPR_MAX_INT32) {
|
||||
return (c - KPR_MAX_INT32) - 1;
|
||||
} else {
|
||||
return (((int)c + (int) -(KPR_MAX_INT32)) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern picokpr_StrArrOffset picokpr_getProdNameOfs(picokpr_Preproc preproc, picokpr_ProdArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rProdArr[ofs]);
|
||||
|
||||
return p[KPR_PROD_PRODNAMEOFS_OFS+0] +
|
||||
256*p[KPR_PROD_PRODNAMEOFS_OFS+1] +
|
||||
256*256*p[KPR_PROD_PRODNAMEOFS_OFS+2] +
|
||||
256U*256U*256U*p[KPR_PROD_PRODNAMEOFS_OFS+3];
|
||||
|
||||
}
|
||||
|
||||
|
||||
extern picokpr_TokArrOffset picokpr_getProdATokOfs(picokpr_Preproc preproc, picokpr_ProdArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rProdArr[ofs]);
|
||||
|
||||
return p[KPR_PROD_ATOKOFS_OFS+0] + 256*p[KPR_PROD_ATOKOFS_OFS+1];
|
||||
}
|
||||
|
||||
|
||||
extern picokpr_TokArrOffset picokpr_getProdETokOfs(picokpr_Preproc preproc, picokpr_ProdArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rProdArr[ofs]);
|
||||
|
||||
return p[KPR_PROD_ETOKOFS_OFS+0] + 256*p[KPR_PROD_ETOKOFS_OFS+1];
|
||||
}
|
||||
|
||||
/* *****************************************************************************/
|
||||
/* knowledge base access routines for contexts in CtxArr */
|
||||
/* *****************************************************************************/
|
||||
|
||||
extern picoos_int32 picokpr_getCtxArrLen(picokpr_Preproc preproc)
|
||||
{
|
||||
return ((kpr_SubObj)preproc)->rCtxArrLen;
|
||||
}
|
||||
|
||||
extern picokpr_StrArrOffset picokpr_getCtxCtxNameOfs(picokpr_Preproc preproc, picokpr_CtxArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rCtxArr[ofs]);
|
||||
|
||||
return p[KPR_CTX_CTXNAMEOFS_OFS+0] +
|
||||
256*p[KPR_CTX_CTXNAMEOFS_OFS+1] +
|
||||
256*256*p[KPR_CTX_CTXNAMEOFS_OFS+2] +
|
||||
256U*256U*256U*p[KPR_CTX_CTXNAMEOFS_OFS+3];
|
||||
}
|
||||
|
||||
|
||||
extern picokpr_StrArrOffset picokpr_getCtxNetNameOfs(picokpr_Preproc preproc, picokpr_CtxArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rCtxArr[ofs]);
|
||||
|
||||
return p[KPR_CTX_NETNAMEOFS_OFS+0] +
|
||||
256*p[KPR_CTX_NETNAMEOFS_OFS+1] +
|
||||
256*256*p[KPR_CTX_NETNAMEOFS_OFS+2] +
|
||||
256U*256U*256U*p[KPR_CTX_NETNAMEOFS_OFS+3];
|
||||
}
|
||||
|
||||
|
||||
extern picokpr_StrArrOffset picokpr_getCtxProdNameOfs(picokpr_Preproc preproc, picokpr_CtxArrOffset ofs)
|
||||
{
|
||||
picoos_uint8 * p = (picoos_uint8 *)&(((kpr_SubObj)preproc)->rCtxArr[ofs]);
|
||||
|
||||
return p[KPR_CTX_PRODNAMEOFS_OFS+0] +
|
||||
256*p[KPR_CTX_PRODNAMEOFS_OFS+1] +
|
||||
256*256*p[KPR_CTX_PRODNAMEOFS_OFS+2] +
|
||||
256U*256U*256U*p[KPR_CTX_PRODNAMEOFS_OFS+3];
|
||||
}
|
||||
|
||||
/* *****************************************************************************/
|
||||
/* knowledge base access routines for networks */
|
||||
/* *****************************************************************************/
|
||||
|
||||
extern picokpr_VarStrPtr picokpr_getPreprocNetName(picokpr_Preproc preproc)
|
||||
{
|
||||
return ((kpr_SubObj)preproc)->rNetName;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* end */
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picokpr.h
|
||||
*
|
||||
* knowledge handling for text preprocessing
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @addtogroup picokpr
|
||||
|
||||
* <b> Knowledge handling for text preprocessing </b>\n
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PICOKPR_H_
|
||||
#define PICOKPR_H_
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picoknow.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* function to create specialized kb, */
|
||||
/* to be used by picorsrc only */
|
||||
/* ************************************************************/
|
||||
|
||||
pico_status_t picokpr_specializePreprocKnowledgeBase(picoknow_KnowledgeBase this,
|
||||
picoos_Common common);
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* preproc type and getPreproc function */
|
||||
/* ************************************************************/
|
||||
|
||||
/* maximal array length in preproc knowledge */
|
||||
#define NPPMaxStrArrLen 100000000
|
||||
#define NPPMaxLexCatArrLen 65536
|
||||
#define NPPMaxAttrValLen 65536
|
||||
#define NPPMaxOutItemArrLen 65536
|
||||
#define NPPMaxTokArrLen 65536
|
||||
#define NPPMaxProdArrLen 65536
|
||||
#define NPPMaxCtxArrLen 65536
|
||||
|
||||
/* array offset types */
|
||||
typedef picoos_uint32 picokpr_StrArrOffset;
|
||||
typedef picoos_uint16 picokpr_LexCatArrOffset;
|
||||
typedef picoos_uint16 picokpr_AttrValArrOffset;
|
||||
typedef picoos_uint16 picokpr_OutItemArrOffset;
|
||||
typedef picoos_uint16 picokpr_TokArrOffset;
|
||||
typedef picoos_uint16 picokpr_ProdArrOffset;
|
||||
typedef picoos_uint16 picokpr_CtxArrOffset;
|
||||
|
||||
typedef picoos_uchar * picokpr_VarStrPtr;
|
||||
|
||||
typedef picoos_int16 picokpr_LexCat;
|
||||
typedef picoos_uint32 picokpr_TokSetNP;
|
||||
typedef picoos_uint32 picokpr_TokSetWP;
|
||||
|
||||
/* preproc types */
|
||||
typedef struct picokpr_preproc * picokpr_Preproc;
|
||||
|
||||
/* return kb preproc for usage in PU */
|
||||
picokpr_Preproc picokpr_getPreproc(picoknow_KnowledgeBase this);
|
||||
|
||||
|
||||
/* *****************************************************************************/
|
||||
/* access routines */
|
||||
/* *****************************************************************************/
|
||||
|
||||
/* knowledge base access routines for strings in StrArr */
|
||||
extern picokpr_VarStrPtr picokpr_getVarStrPtr(picokpr_Preproc preproc, picokpr_StrArrOffset ofs);
|
||||
extern picoos_bool picokpr_isEqual (picokpr_Preproc preproc, picoos_uchar str[], picoos_int32 len__9, picokpr_StrArrOffset str2);
|
||||
extern picoos_bool picokpr_isEqualHead (picokpr_Preproc preproc, picoos_uchar str[], picoos_int32 len__10, picokpr_StrArrOffset head);
|
||||
extern picoos_bool picokpr_isEqualMid (picokpr_Preproc preproc, picoos_uchar str[], picoos_int32 len__11, picokpr_StrArrOffset mid);
|
||||
extern picoos_bool picokpr_isEqualTail (picokpr_Preproc preproc, picoos_uchar str[], picoos_int32 len__12, picokpr_StrArrOffset tail);
|
||||
|
||||
/* knowledge base access routines for lexical categories in LexCatArr */
|
||||
extern picokpr_LexCat picokpr_getLexCat(picokpr_Preproc preproc, picokpr_LexCatArrOffset ofs);
|
||||
|
||||
/* knowledge base access routines for AttrVal fields in AttrValArr */
|
||||
extern picoos_int32 picokpr_getAttrValArrInt32(picokpr_Preproc preproc, picokpr_AttrValArrOffset ofs);
|
||||
|
||||
/* knowledge base access routines for out items fields in OutItemArr */
|
||||
extern picokpr_StrArrOffset picokpr_getOutItemStrOfs(picokpr_Preproc preproc, picokpr_OutItemArrOffset ofs);
|
||||
extern picokpr_VarStrPtr picokpr_getOutItemStr(picokpr_Preproc preproc, picokpr_OutItemArrOffset ofs);
|
||||
extern picoos_int32 picokpr_getOutItemType(picokpr_Preproc preproc, picokpr_OutItemArrOffset ofs);
|
||||
extern picoos_int32 picokpr_getOutItemVal(picokpr_Preproc preproc, picokpr_OutItemArrOffset ofs);
|
||||
extern picokpr_OutItemArrOffset picokpr_getOutItemArgOfs(picokpr_Preproc preproc, picokpr_OutItemArrOffset ofs);
|
||||
extern picokpr_OutItemArrOffset picokpr_getOutItemNextOfs(picokpr_Preproc preproc, picokpr_OutItemArrOffset ofs);
|
||||
|
||||
/* knowledge base access routines for tokens in TokArr */
|
||||
extern picokpr_TokSetNP picokpr_getTokSetNP(picokpr_Preproc preproc, picokpr_TokArrOffset ofs);
|
||||
extern picokpr_TokSetWP picokpr_getTokSetWP(picokpr_Preproc preproc, picokpr_TokArrOffset ofs);
|
||||
extern picokpr_TokArrOffset picokpr_getTokNextOfs(picokpr_Preproc preproc, picokpr_TokArrOffset ofs);
|
||||
extern picokpr_TokArrOffset picokpr_getTokAltLOfs(picokpr_Preproc preproc, picokpr_TokArrOffset ofs);
|
||||
extern picokpr_TokArrOffset picokpr_getTokAltROfs(picokpr_Preproc preproc, picokpr_TokArrOffset ofs);
|
||||
extern picokpr_AttrValArrOffset picokpr_getTokAttribOfs(picokpr_Preproc preproc, picokpr_TokArrOffset ofs);
|
||||
|
||||
/* knowledge base access routines for productions in ProdArr */
|
||||
extern picoos_int32 picokpr_getProdArrLen(picokpr_Preproc preproc);
|
||||
extern picoos_int32 picokpr_getProdPrefCost(picokpr_Preproc preproc, picokpr_ProdArrOffset ofs);
|
||||
extern picokpr_StrArrOffset picokpr_getProdNameOfs(picokpr_Preproc preproc, picokpr_ProdArrOffset ofs);
|
||||
extern picokpr_TokArrOffset picokpr_getProdATokOfs(picokpr_Preproc preproc, picokpr_ProdArrOffset ofs);
|
||||
extern picokpr_TokArrOffset picokpr_getProdETokOfs(picokpr_Preproc preproc, picokpr_ProdArrOffset ofs);
|
||||
|
||||
/* knowledge base access routines for contexts in CtxArr */
|
||||
extern picoos_int32 picokpr_getCtxArrLen(picokpr_Preproc preproc);
|
||||
extern picokpr_StrArrOffset picokpr_getCtxCtxNameOfs(picokpr_Preproc preproc, picokpr_CtxArrOffset ofs);
|
||||
extern picokpr_StrArrOffset picokpr_getCtxNetNameOfs(picokpr_Preproc preproc, picokpr_CtxArrOffset ofs);
|
||||
extern picokpr_StrArrOffset picokpr_getCtxProdNameOfs(picokpr_Preproc preproc, picokpr_CtxArrOffset ofs);
|
||||
|
||||
/* knowledge base access routines for preprocs */
|
||||
extern picokpr_VarStrPtr picokpr_getPreprocNetName(picokpr_Preproc preproc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*PICOKPR_H_*/
|
||||
+1118
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picoktab.h
|
||||
*
|
||||
* symbol tables needed at runtime
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @addtogroup picoktab
|
||||
|
||||
* <b> Symbol tables needed at runtime </b>\n
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PICOKTAB_H_
|
||||
#define PICOKTAB_H_
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picoknow.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* fixed IDs type and functions */
|
||||
/* ************************************************************/
|
||||
|
||||
/** object : FixedIds
|
||||
* shortcut : ids
|
||||
*/
|
||||
typedef struct picoktab_fixed_ids * picoktab_FixedIds;
|
||||
|
||||
typedef struct picoktab_fixed_ids {
|
||||
picoos_uint8 phonStartId;
|
||||
picoos_uint8 phonTermId;
|
||||
} picoktab_fixed_ids_t;
|
||||
|
||||
/* to be used by picorsrc only */
|
||||
pico_status_t picoktab_specializeIdsKnowledgeBase(picoknow_KnowledgeBase this,
|
||||
picoos_Common common);
|
||||
|
||||
picoktab_FixedIds picoktab_getFixedIds(picoknow_KnowledgeBase this);
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* Graphs type and functions */
|
||||
/* ************************************************************/
|
||||
|
||||
typedef struct picoktab_graphs *picoktab_Graphs;
|
||||
|
||||
/* to be used by picorsrc only */
|
||||
pico_status_t picoktab_specializeGraphsKnowledgeBase(picoknow_KnowledgeBase this,
|
||||
picoos_Common common);
|
||||
|
||||
/* return kb graphs for usage in PU */
|
||||
picoktab_Graphs picoktab_getGraphs(picoknow_KnowledgeBase this);
|
||||
|
||||
/* graph access routine: if the desired graph 'utf8graph' exists in
|
||||
the graph table a graph offset > 0 is returned, which then can be
|
||||
used to access the properties */
|
||||
picoos_uint32 picoktab_graphOffset(const picoktab_Graphs this,
|
||||
picoos_uchar * utf8graph);
|
||||
|
||||
|
||||
/* check if UTF8 char 'graph' has property vowellike, return non-zero
|
||||
if 'ch' has the property, 0 otherwise */
|
||||
picoos_uint8 picoktab_hasVowellikeProp(const picoktab_Graphs this,
|
||||
const picoos_uint8 *graph,
|
||||
const picoos_uint8 graphlenmax);
|
||||
|
||||
/* graph properties access routines: if graph with offset 'graphsOffset' has the
|
||||
desired property, returns TRUE if 'ch' has the property, FALSE otherwise */
|
||||
picoos_bool picoktab_getIntPropTokenType(const picoktab_Graphs this,
|
||||
picoos_uint32 graphsOffset,
|
||||
picoos_uint8 *stokenType);
|
||||
picoos_bool picoktab_getIntPropTokenSubType(const picoktab_Graphs this,
|
||||
picoos_uint32 graphsOffset,
|
||||
picoos_int8 *stokenSubType);
|
||||
picoos_bool picoktab_getIntPropValue(const picoktab_Graphs this,
|
||||
picoos_uint32 graphsOffset,
|
||||
picoos_uint32 *value);
|
||||
picoos_bool picoktab_getStrPropLowercase(const picoktab_Graphs this,
|
||||
picoos_uint32 graphsOffset,
|
||||
picoos_uchar *lowercase);
|
||||
picoos_bool picoktab_getStrPropGraphsubs1(const picoktab_Graphs this,
|
||||
picoos_uint32 graphsOffset,
|
||||
picoos_uchar *graphsubs1);
|
||||
picoos_bool picoktab_getStrPropGraphsubs2(const picoktab_Graphs this,
|
||||
picoos_uint32 graphsOffset,
|
||||
picoos_uchar *graphsubs2);
|
||||
picoos_bool picoktab_getIntPropPunct(const picoktab_Graphs this,
|
||||
picoos_uint32 graphsOffset,
|
||||
picoos_uint8 *info1,
|
||||
picoos_uint8 *info2);
|
||||
|
||||
picoos_uint16 picoktab_graphsGetNumEntries(const picoktab_Graphs this);
|
||||
void picoktab_graphsGetGraphInfo(const picoktab_Graphs this,
|
||||
picoos_uint16 graphIndex, picoos_uchar * from, picoos_uchar * to,
|
||||
picoos_uint8 * propset,
|
||||
picoos_uint8 * stokenType, picoos_uint8 * stokenSubType,
|
||||
picoos_uint8 * value, picoos_uchar * lowercase,
|
||||
picoos_uchar * graphsubs1, picoos_uchar * graphsubs2,
|
||||
picoos_uint8 * punct);
|
||||
|
||||
|
||||
/* ************************************************************/
|
||||
/* Phones type and functions */
|
||||
/* ************************************************************/
|
||||
|
||||
/* to be used by picorsrc only */
|
||||
pico_status_t picoktab_specializePhonesKnowledgeBase(picoknow_KnowledgeBase this,
|
||||
picoos_Common common);
|
||||
|
||||
typedef struct picoktab_phones *picoktab_Phones;
|
||||
|
||||
/* return kb Phones for usage in PU */
|
||||
picoktab_Phones picoktab_getPhones(picoknow_KnowledgeBase this);
|
||||
|
||||
/* check if 'ch' has a property, return non-zero if 'ch' has the
|
||||
property, 0 otherwise */
|
||||
picoos_uint8 picoktab_hasVowelProp(const picoktab_Phones this,
|
||||
const picoos_uint8 ch);
|
||||
picoos_uint8 picoktab_hasDiphthProp(const picoktab_Phones this,
|
||||
const picoos_uint8 ch);
|
||||
picoos_uint8 picoktab_hasGlottProp(const picoktab_Phones this,
|
||||
const picoos_uint8 ch);
|
||||
picoos_uint8 picoktab_hasNonsyllvowelProp(const picoktab_Phones this,
|
||||
const picoos_uint8 ch);
|
||||
picoos_uint8 picoktab_hasSyllconsProp(const picoktab_Phones this,
|
||||
const picoos_uint8 ch);
|
||||
|
||||
/* to speed up processing for often used combinations of properties
|
||||
the following functions are provided, which check if the property
|
||||
combination is true for 'ch' */
|
||||
picoos_bool picoktab_isSyllCarrier(const picoktab_Phones this,
|
||||
const picoos_uint8 ch);
|
||||
|
||||
/* some properties can be assigned to a single sym only, check if 'ch'
|
||||
is a special sym, return TRUE if it is the special sym, FALSE
|
||||
otherwise */
|
||||
picoos_bool picoktab_isPrimstress(const picoktab_Phones this,
|
||||
const picoos_uint8 ch);
|
||||
picoos_bool picoktab_isSecstress(const picoktab_Phones this,
|
||||
const picoos_uint8 ch);
|
||||
picoos_bool picoktab_isSyllbound(const picoktab_Phones this,
|
||||
const picoos_uint8 ch);
|
||||
picoos_bool picoktab_isWordbound(const picoktab_Phones this,
|
||||
const picoos_uint8 ch);
|
||||
picoos_bool picoktab_isPause(const picoktab_Phones this,
|
||||
const picoos_uint8 ch);
|
||||
|
||||
/* get specific sym values */
|
||||
picoos_uint8 picoktab_getPrimstressID(const picoktab_Phones this);
|
||||
picoos_uint8 picoktab_getSecstressID(const picoktab_Phones this);
|
||||
picoos_uint8 picoktab_getSyllboundID(const picoktab_Phones this);
|
||||
picoos_uint8 picoktab_getWordboundID(const picoktab_Phones this);
|
||||
picoos_uint8 picoktab_getPauseID(const picoktab_Phones this);
|
||||
|
||||
/* ************************************************************/
|
||||
/* Pos type and functions */
|
||||
/* ************************************************************/
|
||||
|
||||
/* to be used by picorsrc only */
|
||||
pico_status_t picoktab_specializePosKnowledgeBase(picoknow_KnowledgeBase this,
|
||||
picoos_Common common);
|
||||
|
||||
typedef struct picoktab_pos *picoktab_Pos;
|
||||
|
||||
#define PICOKTAB_MAXNRPOS_IN_COMB 8
|
||||
|
||||
/* return kb Pos for usage in PU */
|
||||
picoktab_Pos picoktab_getPos(picoknow_KnowledgeBase this);
|
||||
|
||||
/* returns TRUE if 'pos' is the ID of a unique (ie. non-combined) POS,
|
||||
returns FALSE otherwise */
|
||||
picoos_bool picoktab_isUniquePos(const picoktab_Pos this,
|
||||
const picoos_uint8 pos);
|
||||
|
||||
/* returns TRUE if the non-combined 'pos' is one of the POSes in the
|
||||
combined POS group 'posgroup, returns FALSE otherwise. Note: if
|
||||
'posgroup' is itself non-combined, this function returns TRUE if it
|
||||
matches with 'pos', and FALSE otherwise */
|
||||
picoos_bool picoktab_isPartOfPosGroup(const picoktab_Pos this,
|
||||
const picoos_uint8 pos,
|
||||
const picoos_uint8 posgroup);
|
||||
|
||||
/* return the combined POS group ID that is a representative ID for
|
||||
all the 'poslistlen' POSes (which can be combined themselves) in
|
||||
poslist. Returns '0' in case of error. */
|
||||
picoos_uint8 picoktab_getPosGroup(const picoktab_Pos this,
|
||||
const picoos_uint8 *poslist,
|
||||
const picoos_uint8 poslistlen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*PICOKTAB_H_*/
|
||||
+2309
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,550 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picoos.h
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @addtogroup picoos
|
||||
|
||||
* <b> Operating system generalization module </b>\n
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PICOOS_H_
|
||||
#define PICOOS_H_
|
||||
|
||||
#include "picodefs.h"
|
||||
#include "picopal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* some "switch" used in picopal and in picocep ... */
|
||||
#define PICOOS_DIV_USE_INV PICOPAL_DIV_USE_INV
|
||||
|
||||
/* *************************************************/
|
||||
/* types */
|
||||
/* *************************************************/
|
||||
|
||||
typedef picopal_uint8 picoos_uint8;
|
||||
typedef picopal_uint16 picoos_uint16;
|
||||
typedef picopal_uint32 picoos_uint32;
|
||||
|
||||
typedef picopal_int8 picoos_int8;
|
||||
typedef picopal_int16 picoos_int16;
|
||||
typedef picopal_int32 picoos_int32;
|
||||
|
||||
typedef picopal_double picoos_double;
|
||||
typedef picopal_single picoos_single;
|
||||
|
||||
typedef picopal_char picoos_char;
|
||||
typedef picopal_uchar picoos_uchar;
|
||||
|
||||
typedef picopal_uint8 picoos_bool;
|
||||
|
||||
typedef picopal_objsize_t picoos_objsize_t;
|
||||
typedef picopal_ptrdiff_t picoos_ptrdiff_t;
|
||||
|
||||
/* *************************************************/
|
||||
/* functions */
|
||||
/* *************************************************/
|
||||
|
||||
|
||||
picoos_int32 picoos_atoi(const picoos_char *);
|
||||
picoos_int8 picoos_strcmp(const picoos_char *, const picoos_char *);
|
||||
picoos_int8 picoos_strncmp(const picoos_char *a, const picoos_char *b, picoos_objsize_t siz);
|
||||
picoos_uint32 picoos_strlen(const picoos_char *);
|
||||
picoos_char * picoos_strchr(const picoos_char *, picoos_char);
|
||||
picoos_char *picoos_strstr(const picoos_char *s, const picoos_char *substr);
|
||||
picoos_int16 picoos_slprintf(picoos_char * b, picoos_uint32 bsize, const picoos_char *f, ...);
|
||||
picoos_char * picoos_strcpy(picoos_char *, const picoos_char *);
|
||||
picoos_char * picoos_strcat(picoos_char *, const picoos_char *);
|
||||
|
||||
/* copies 'length' bytes from 'src' to 'dest'. (regions may be overlapping) no error checks! */
|
||||
void * picoos_mem_copy(const void * src, void * dst, picoos_objsize_t length);
|
||||
|
||||
/* safe versions */
|
||||
picoos_objsize_t picoos_strlcpy(picoos_char *dst, const picoos_char *src, picoos_objsize_t siz);
|
||||
void * picoos_mem_set(void * dest, picoos_uint8 byte_val, picoos_objsize_t length);
|
||||
|
||||
picoos_double picoos_cos(const picoos_double cos_arg);
|
||||
picoos_double picoos_sin(const picoos_double sin_arg);
|
||||
picoos_double picoos_fabs(const picoos_double fabs_arg);
|
||||
|
||||
picoos_double picoos_quick_exp(const picoos_double y);
|
||||
|
||||
|
||||
void picoos_get_sep_part_str (picoos_char string[], picoos_int32 stringlen, picoos_int32 * ind, picoos_char sepCh, picoos_char part[], picoos_int32 maxsize, picoos_uint8 * done);
|
||||
pico_status_t picoos_string_to_uint32 (picoos_char str[], picoos_uint32 * res);
|
||||
pico_status_t picoos_string_to_int32 (picoos_char str[], picoos_int32 * res);
|
||||
|
||||
/* *****************************************************************/
|
||||
/* "Common" */
|
||||
/* *****************************************************************/
|
||||
/* picoos_common is a collection of basic functionalities that must be globally accesible from every "big" function.
|
||||
* It includes pointers to the MemoryManasger, ExceptionManager and a list of open files. */
|
||||
|
||||
typedef struct memory_manager * picoos_MemoryManager;
|
||||
typedef struct picoos_exception_manager * picoos_ExceptionManager;
|
||||
typedef struct picoos_file * picoos_File;
|
||||
|
||||
|
||||
/** object : Common
|
||||
* shortcut : common
|
||||
*
|
||||
*/
|
||||
typedef struct picoos_common * picoos_Common;
|
||||
|
||||
/* the picoos_common structure itself is exported so no access functions are needed. Handle with care! (might be changed later) */
|
||||
typedef struct picoos_common {
|
||||
picoos_ExceptionManager em;
|
||||
picoos_MemoryManager mm;
|
||||
picoos_File fileList;
|
||||
} picoos_common_t;
|
||||
|
||||
picoos_Common picoos_newCommon(picoos_MemoryManager mm);
|
||||
|
||||
void picoos_disposeCommon(picoos_MemoryManager mm, picoos_Common * this);
|
||||
|
||||
|
||||
/* *****************************************************************/
|
||||
/* Memory Management */
|
||||
/* *****************************************************************/
|
||||
|
||||
typedef picoos_char * byte_ptr_t;
|
||||
|
||||
#define PICOOS_ALIGN_SIZE 8
|
||||
|
||||
|
||||
|
||||
void * picoos_raw_malloc(byte_ptr_t raw_mem,
|
||||
picoos_objsize_t raw_mem_size, picoos_objsize_t alloc_size,
|
||||
byte_ptr_t * rest_mem, picoos_objsize_t * rest_mem_size);
|
||||
|
||||
/**
|
||||
* Creates a new memory manager object for the specified raw memory
|
||||
* block. 'enableProtMem' enables or disables memory protection
|
||||
* functionality; if disabled, picoos_protectMem() has no effect.
|
||||
*/
|
||||
picoos_MemoryManager picoos_newMemoryManager(
|
||||
void *raw_memory,
|
||||
picoos_objsize_t size,
|
||||
picoos_bool enableMemProt);
|
||||
|
||||
|
||||
|
||||
void picoos_disposeMemoryManager(picoos_MemoryManager * mm);
|
||||
|
||||
|
||||
void * picoos_allocate(picoos_MemoryManager this, picoos_objsize_t byteSize);
|
||||
void picoos_deallocate(picoos_MemoryManager this, void * * adr);
|
||||
|
||||
/* the following memory manager routines are for testing and
|
||||
debugging purposes */
|
||||
|
||||
/**
|
||||
* Same as picoos_allocate, but write access to the memory block may be
|
||||
* prohibited by a subsequent call to picoos_protectMem().
|
||||
*/
|
||||
void *picoos_allocProtMem(picoos_MemoryManager mm, picoos_objsize_t byteSize);
|
||||
|
||||
/**
|
||||
* Releases a memory block previously allocated by picoos_allocProtMem().
|
||||
*/
|
||||
void picoos_deallocProtMem(picoos_MemoryManager mm, void **addr);
|
||||
|
||||
/**
|
||||
* Enables or disables write protection of a memory block previously
|
||||
* allocated by picoos_allocProtMem(). If write protection is enabled,
|
||||
* any subsequent write access will cause a segmentation fault.
|
||||
*/
|
||||
void picoos_protectMem(
|
||||
picoos_MemoryManager mm,
|
||||
void *addr,
|
||||
picoos_objsize_t len,
|
||||
picoos_bool enable);
|
||||
|
||||
void picoos_getMemUsage(
|
||||
picoos_MemoryManager this,
|
||||
picoos_bool resetIncremental,
|
||||
picoos_int32 *usedBytes,
|
||||
picoos_int32 *incrUsedBytes,
|
||||
picoos_int32 *maxUsedBytes);
|
||||
|
||||
void picoos_showMemUsage(
|
||||
picoos_MemoryManager this,
|
||||
picoos_bool incremental,
|
||||
picoos_bool resetIncremental);
|
||||
|
||||
/* *****************************************************************/
|
||||
/* Exception Management */
|
||||
/* *****************************************************************/
|
||||
/** object : ExceptionManager
|
||||
* shortcut : em
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define PICOOS_MAX_EXC_MSG_LEN 512
|
||||
#define PICOOS_MAX_WARN_MSG_LEN 64
|
||||
#define PICOOS_MAX_NUM_WARNINGS 8
|
||||
|
||||
void picoos_setErrorMsg(picoos_char * dst, picoos_objsize_t siz,
|
||||
picoos_int16 code, picoos_char * base, const picoos_char *fmt, ...);
|
||||
|
||||
|
||||
picoos_ExceptionManager picoos_newExceptionManager(picoos_MemoryManager mm);
|
||||
|
||||
void picoos_disposeExceptionManager(picoos_MemoryManager mm,
|
||||
picoos_ExceptionManager * this);
|
||||
|
||||
|
||||
void picoos_emReset(picoos_ExceptionManager this);
|
||||
|
||||
/* For convenience, this function returns the resulting exception code of 'this'
|
||||
* (as would be returned by emGetExceptionCode).
|
||||
* The return value therefore is NOT the status of raising
|
||||
* the error! */
|
||||
pico_status_t picoos_emRaiseException(picoos_ExceptionManager this,
|
||||
pico_status_t exceptionCode, picoos_char * baseMessage, picoos_char * fmt, ...);
|
||||
|
||||
pico_status_t picoos_emGetExceptionCode(picoos_ExceptionManager this);
|
||||
|
||||
void picoos_emGetExceptionMessage(picoos_ExceptionManager this, picoos_char * msg, picoos_uint16 maxsize);
|
||||
|
||||
void picoos_emRaiseWarning(picoos_ExceptionManager this,
|
||||
pico_status_t warningCode, picoos_char * baseMessage, picoos_char * fmt, ...);
|
||||
|
||||
picoos_uint8 picoos_emGetNumOfWarnings(picoos_ExceptionManager this);
|
||||
|
||||
pico_status_t picoos_emGetWarningCode(picoos_ExceptionManager this, picoos_uint8 warnNum);
|
||||
|
||||
void picoos_emGetWarningMessage(picoos_ExceptionManager this, picoos_uint8 warnNum, picoos_char * msg, picoos_uint16 maxsize);
|
||||
|
||||
|
||||
|
||||
|
||||
/* *****************************************************************/
|
||||
/* File Access */
|
||||
/* *****************************************************************/
|
||||
|
||||
#define picoos_MaxFileNameLen 512
|
||||
#define picoos_MaxKeyLen 512
|
||||
#define picoos_MaxPathLen 512
|
||||
#define picoos_MaxPathListLen 2048
|
||||
|
||||
typedef picoos_char picoos_Key[picoos_MaxKeyLen];
|
||||
typedef picoos_char picoos_FileName[picoos_MaxFileNameLen];
|
||||
typedef picoos_char picoos_Path[picoos_MaxPathLen];
|
||||
typedef picoos_char picoos_PathList[picoos_MaxPathListLen];
|
||||
|
||||
|
||||
/* ***** Sequential binary file access ******/
|
||||
|
||||
/* Remark: 'ReadByte', 'ReadBytes' and 'ReadVar' may be mixed;
|
||||
'WriteByte', 'WriteBytes' and 'WriteVar' may be mixed. */
|
||||
|
||||
/* Open existing binary file for read access. */
|
||||
picoos_uint8 picoos_OpenBinary(picoos_Common g, picoos_File * f, picoos_char name[]);
|
||||
|
||||
|
||||
/* Read next byte from file 'f'. */
|
||||
picoos_uint8 picoos_ReadByte(picoos_File f, picoos_uint8 * by);
|
||||
|
||||
/* Read next 'len' bytes from 'f' into 'bytes'; 'len' returns the
|
||||
number of bytes actually read (may be smaller than requested
|
||||
length if 'bytes' is too small to hold all bytes or at end of file).
|
||||
Remark: 'bytes' is compabtible with any variable of any size. */
|
||||
picoos_uint8 picoos_ReadBytes(picoos_File f, picoos_uint8 bytes[],
|
||||
picoos_uint32 * len);
|
||||
|
||||
|
||||
/* Create new binary file.
|
||||
If 'key' is not empty, the file is encrypted with 'key'. */
|
||||
picoos_uint8 picoos_CreateBinary(picoos_Common g, picoos_File * f, picoos_char name[]);
|
||||
|
||||
picoos_uint8 picoos_WriteByte(picoos_File f, picoos_char by);
|
||||
|
||||
/* Writes 'len' bytes from 'bytes' onto file 'f'; 'len' returns
|
||||
the number of bytes actually written. */
|
||||
picoos_uint8 picoos_WriteBytes(picoos_File f, const picoos_char bytes[],
|
||||
picoos_int32 * len);
|
||||
|
||||
|
||||
/* Close previously opened binary file. */
|
||||
picoos_uint8 picoos_CloseBinary(picoos_Common g, picoos_File * f);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
pico_status_t picoos_read_le_int16 (picoos_File file, picoos_int16 * val);
|
||||
pico_status_t picoos_read_le_uint16 (picoos_File file, picoos_uint16 * val);
|
||||
pico_status_t picoos_read_le_uint32 (picoos_File file, picoos_uint32 * val);
|
||||
|
||||
|
||||
pico_status_t picoos_read_pi_uint16 (picoos_File file, picoos_uint16 * val);
|
||||
pico_status_t picoos_read_pi_uint32 (picoos_File file, picoos_uint32 * val);
|
||||
|
||||
pico_status_t picoos_write_le_uint16 (picoos_File file, picoos_uint16 val);
|
||||
pico_status_t picoos_write_le_uint32 (picoos_File file, picoos_uint32 val);
|
||||
|
||||
/*
|
||||
pico_status_t picoos_write_pi_uint32 (picoos_File file, const picoos_uint32 val);
|
||||
|
||||
pico_status_t picoos_write_pi_uint16 (picoos_File file, const picoos_uint16 val);
|
||||
*/
|
||||
|
||||
|
||||
/* **************************************************************************************/
|
||||
/* *** general file routines *****/
|
||||
|
||||
/* Returns whether end of file was encountered in previous
|
||||
read operation. */
|
||||
picoos_bool picoos_Eof(picoos_File f);
|
||||
|
||||
/* sets the file pointer to
|
||||
'pos' bytes from beginning (first byte = byte 0). This
|
||||
routine should only be used for binary files. */
|
||||
picoos_bool picoos_SetPos(picoos_File f, picoos_int32 pos);
|
||||
|
||||
/* Get position from file 'f'. */
|
||||
picoos_bool picoos_GetPos(picoos_File f, picoos_uint32 * pos);
|
||||
|
||||
/* Returns the length of the file in bytes. */
|
||||
picoos_bool picoos_FileLength(picoos_File f, picoos_uint32 * len);
|
||||
|
||||
/* Return full name of file 'f'. */
|
||||
picoos_bool picoos_Name(picoos_File f, picoos_char name[], picoos_uint32 maxsize);
|
||||
|
||||
/* Returns whether file 'name' exists or not. */
|
||||
picoos_bool picoos_FileExists(picoos_Common g, picoos_char name[] /*, picoos_char ckey[] */);
|
||||
|
||||
/* Delete a file. */
|
||||
picoos_bool picoos_Delete(picoos_char name[]);
|
||||
|
||||
/* Rename a file. */
|
||||
picoos_bool picoos_Rename(picoos_char oldName[], picoos_char newName[]);
|
||||
|
||||
|
||||
/* *****************************************************************/
|
||||
/* Sampled Data Files */
|
||||
/* *****************************************************************/
|
||||
|
||||
#define SAMPLE_FREQ_16KHZ (picoos_uint32) 16000
|
||||
|
||||
typedef enum {
|
||||
FILE_TYPE_WAV,
|
||||
FILE_TYPE_AU,
|
||||
FILE_TYPE_RAW,
|
||||
FILE_TYPE_OTHER
|
||||
} wave_file_type_t;
|
||||
|
||||
typedef enum {
|
||||
FORMAT_TAG_LIN = 1, /**< linear 16-bit encoding */
|
||||
FORMAT_TAG_ALAW = 6, /**< a-law encoding, 8 bit */
|
||||
FORMAT_TAG_ULAW = 7 /**< u-law encoding, 8 bit */
|
||||
/* there are many more */
|
||||
} wave_format_tag_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
/* values corresponding RIFF wFormatTag */
|
||||
PICOOS_ENC_LIN = FORMAT_TAG_LIN, /**< linear 16-bit encoding; standard */
|
||||
PICOOS_ENC_ALAW = FORMAT_TAG_ALAW, /**< a-law encoding, 8 bit */
|
||||
PICOOS_ENC_ULAW = FORMAT_TAG_ULAW, /**< u-law encoding, 8 bit */
|
||||
/* values outside RIFF wFormatTag values (above 4100) */
|
||||
PICOOS_ENC_OTHER = 5000 /**< other; (treated as raw) */
|
||||
} picoos_encoding_t;
|
||||
|
||||
typedef struct picoos_sd_file * picoos_SDFile;
|
||||
|
||||
/* SDFile input functions */
|
||||
|
||||
/* orig. comment from SDInOut.def
|
||||
Opens sampled data file 'fileName' for input and returns
|
||||
the encoding 'enc' of the file, sampling rate 'sf',
|
||||
nr of samples 'nrSamples', and a handle to the opened file
|
||||
in 'sdFile'.
|
||||
|
||||
If 'fileName' is empty, the input is taken from the direct
|
||||
acoustic input using the sampling rate specified by
|
||||
"SetRawDefaults". In this case, 'encoding' returns 'EncLin',
|
||||
and 'nrSamples' returns 0.
|
||||
|
||||
The file format is taken from the file name extension:
|
||||
".wav" --> wav file
|
||||
".au" --> au file
|
||||
other extensions --> headerless files
|
||||
|
||||
For wav and au files, the sampling rate and encoding are taken
|
||||
from the file header and returned in 'sf' and 'enc'. For
|
||||
headerless files, 'sf' and 'enc' are taken from the
|
||||
most recently set default values (procedure SetRawDefaults).
|
||||
|
||||
'done' returns whether the sampled data file was successfully
|
||||
opened. */
|
||||
extern picoos_bool picoos_sdfOpenIn (picoos_Common g, picoos_SDFile * sdFile, picoos_char fileName[], picoos_uint32 * sf, picoos_encoding_t * enc, picoos_uint32 * nrSamples);
|
||||
|
||||
|
||||
extern picoos_bool picoos_sdfGetSamples (picoos_SDFile sdFile, picoos_uint32 start, picoos_uint32 * nrSamples, picoos_int16 samples[]);
|
||||
|
||||
|
||||
extern picoos_bool picoos_sdfCloseIn (picoos_Common g, picoos_SDFile * sdFile);
|
||||
|
||||
|
||||
/* SDFile output functions*/
|
||||
|
||||
extern picoos_bool picoos_sdfOpenOut (picoos_Common g, picoos_SDFile * sdFile, picoos_char fileName[], int sf, picoos_encoding_t enc);
|
||||
|
||||
|
||||
extern picoos_bool picoos_sdfPutSamples (picoos_SDFile sdFile, picoos_uint32 nrSamples, picoos_int16 samples[]);
|
||||
|
||||
/*
|
||||
extern picoos_bool picoos_AbortOutput (picoos_SDFile sdFile);
|
||||
|
||||
|
||||
extern picoos_bool picoos_ResumeOutput (picoos_SDFile sdFile);
|
||||
|
||||
|
||||
extern picoos_bool picoos_FlushOutput (picoos_SDFile sdFile);
|
||||
*/
|
||||
|
||||
extern picoos_bool picoos_sdfCloseOut (picoos_Common g, picoos_SDFile * sdFile);
|
||||
|
||||
|
||||
/* *****************************************************************/
|
||||
/* File Headers */
|
||||
/* *****************************************************************/
|
||||
|
||||
#define PICOOS_MAX_FIELD_STRING_LEN 32 /* including terminating char */
|
||||
|
||||
#define PICOOS_MAX_NUM_HEADER_FIELDS 10
|
||||
#define PICOOS_NUM_BASIC_HEADER_FIELDS 5
|
||||
|
||||
#define PICOOS_HEADER_NAME 0
|
||||
#define PICOOS_HEADER_VERSION 1
|
||||
#define PICOOS_HEADER_DATE 2
|
||||
#define PICOOS_HEADER_TIME 3
|
||||
#define PICOOS_HEADER_CONTENT_TYPE 4
|
||||
|
||||
#define PICOOS_MAX_HEADER_STRING_LEN (PICOOS_MAX_NUM_HEADER_FIELDS * (2 * PICOOS_MAX_FIELD_STRING_LEN))
|
||||
|
||||
typedef picoos_char picoos_field_string_t[PICOOS_MAX_FIELD_STRING_LEN];
|
||||
|
||||
typedef picoos_char picoos_header_string_t[PICOOS_MAX_HEADER_STRING_LEN];
|
||||
|
||||
typedef enum {PICOOS_FIELD_IGNORE, PICOOS_FIELD_EQUAL, PICOOS_FIELD_COMPAT} picoos_compare_op_t;
|
||||
|
||||
/* private */
|
||||
typedef struct picoos_file_header_field {
|
||||
picoos_field_string_t key;
|
||||
picoos_field_string_t value;
|
||||
picoos_compare_op_t op;
|
||||
} picoos_file_header_field_t;
|
||||
|
||||
/* public */
|
||||
typedef struct picoos_file_header * picoos_FileHeader;
|
||||
typedef struct picoos_file_header {
|
||||
picoos_uint8 numFields;
|
||||
picoos_file_header_field_t field[PICOOS_MAX_NUM_HEADER_FIELDS];
|
||||
} picoos_file_header_t;
|
||||
|
||||
|
||||
pico_status_t picoos_clearHeader(picoos_FileHeader header);
|
||||
|
||||
pico_status_t picoos_setHeaderField(picoos_FileHeader header, picoos_uint8 index, picoos_char * key, picoos_char * value, picoos_compare_op_t op);
|
||||
|
||||
/* caller has to make sure allocated space at key and value are large enough to hold a picoos_field_string */
|
||||
pico_status_t picoos_getHeaderField(picoos_FileHeader header, picoos_uint8 index, picoos_field_string_t key, picoos_field_string_t value, picoos_compare_op_t * op);
|
||||
|
||||
/* caller has to make sure allocated space at str is large enough to hold the header in question */
|
||||
/*
|
||||
pico_status_t picoos_hdrToString(picoos_FileHeader header, picoos_header_string_t str);
|
||||
*/
|
||||
|
||||
pico_status_t picoos_hdrParseHeader(picoos_FileHeader header, picoos_header_string_t str);
|
||||
|
||||
pico_status_t picoos_getSVOXHeaderString(picoos_char * str, picoos_uint8 * len, picoos_uint32 maxlen);
|
||||
|
||||
pico_status_t picoos_readPicoHeader(picoos_File f, picoos_uint32 * headerlen);
|
||||
|
||||
|
||||
|
||||
/* *****************************************************************/
|
||||
/* String search and compare operations */
|
||||
/* *****************************************************************/
|
||||
|
||||
|
||||
picoos_uint8 picoos_has_extension(const picoos_char *str, const picoos_char *suf);
|
||||
|
||||
/* *****************************************************************/
|
||||
/* String/Number Manipulations (might be moved to picopal) */
|
||||
/* *****************************************************************/
|
||||
|
||||
pico_status_t picoos_string_to_int32(picoos_char str[],
|
||||
picoos_int32 * res);
|
||||
|
||||
pico_status_t picoos_string_to_uint32(picoos_char str[],
|
||||
picoos_uint32 * res);
|
||||
|
||||
/* 'stringlen' is the part of input string to be considered, possibly not containing NULLC (e.g. result of strlen).
|
||||
* 'maxsize' is the maximal size of 'part' including a byte for the terminating NULLC! */
|
||||
void picoos_get_sep_part_str(picoos_char string[],
|
||||
picoos_int32 stringlen, picoos_int32 * ind, picoos_char sepCh,
|
||||
picoos_char part[], picoos_int32 maxsize, picoos_uint8 * done);
|
||||
|
||||
/* searches for the first contiguous string of printable characters (> ' ') inside fromStr, possibly skipping
|
||||
* chars <= ' ') and returns it in toStr.
|
||||
* fromStr is assumed to be NULLC terminated and toStr is forced to be NULLC terminated within maxsize.
|
||||
* The search is started at *pos inside fromStr and at return, *pos is the position within fromStr after the
|
||||
* found string, or the position after the end of fromStr, if no string was found.
|
||||
* the function returns TRUE if a string was found and fitted toStr, or FALSE otherwise. */
|
||||
picoos_uint8 picoos_get_str (picoos_char * fromStr, picoos_uint32 * pos, picoos_char * toStr, picoos_objsize_t maxsize);
|
||||
|
||||
|
||||
pico_status_t picoos_read_mem_pi_uint16 (picoos_uint8 * data, picoos_uint32 * pos, picoos_uint16 * val);
|
||||
|
||||
pico_status_t picoos_read_mem_pi_uint32 (picoos_uint8 * data, picoos_uint32 * pos, picoos_uint32 * val);
|
||||
|
||||
pico_status_t picoos_write_mem_pi_uint16 (picoos_uint8 * data, picoos_uint32 * pos, picoos_uint16 val);
|
||||
|
||||
|
||||
/* *****************************************************************/
|
||||
/* timer function */
|
||||
/* *****************************************************************/
|
||||
|
||||
void picoos_get_timer(picopal_uint32 * sec, picopal_uint32 * usec);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*PICOOS_H_*/
|
||||
@@ -0,0 +1,554 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picopal.c
|
||||
*
|
||||
* pico platform abstraction layer
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
/* GCC does not supporte #pragma message */
|
||||
#if !defined(__GNUC__)
|
||||
#define PRAGMA_MESSAGE
|
||||
#endif
|
||||
|
||||
#if defined(PRAGMA_MESSAGE) && defined(PICO_PLATFORM)
|
||||
#pragma message("PICO_PLATFORM : is defined externally")
|
||||
#endif
|
||||
|
||||
#if defined(PRAGMA_MESSAGE) && defined(_WIN32)
|
||||
#pragma message("_WIN32 : is defined")
|
||||
#endif
|
||||
|
||||
#if defined(PRAGMA_MESSAGE) && defined(__APPLE__)
|
||||
#pragma message("__APPLE__ : is defined")
|
||||
#endif
|
||||
|
||||
#if defined(PRAGMA_MESSAGE) && defined(__MACH__)
|
||||
#pragma message("__MACH__ : is defined")
|
||||
#endif
|
||||
|
||||
#if defined(PRAGMA_MESSAGE) && defined(macintosh)
|
||||
#pragma message("macintosh : is defined")
|
||||
#endif
|
||||
|
||||
#if defined(PRAGMA_MESSAGE) && defined(linux)
|
||||
#pragma message("linux : is defined")
|
||||
#endif
|
||||
#if defined(PRAGMA_MESSAGE) && defined(__linux__)
|
||||
#pragma message("__linux__ : is defined")
|
||||
#endif
|
||||
#if defined(PRAGMA_MESSAGE) && defined(__linux)
|
||||
#pragma message("__linux : is defined")
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "picodefs.h"
|
||||
#include "picopal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PICO_PLATFORM == PICO_Windows
|
||||
/* use high-resolution timer functions on Windows platform */
|
||||
#define USE_CLOCK 0
|
||||
#else
|
||||
/* use clock() function instead of high-resolution timer on
|
||||
non-Windows platforms */
|
||||
#define USE_CLOCK 1
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#if PICO_PLATFORM == PICO_Windows
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if defined(PRAGMA_MESSAGE)
|
||||
#pragma message("PICO_PLATFORM : " PICO_PLATFORM_STRING)
|
||||
#endif
|
||||
|
||||
|
||||
picopal_int32 picopal_atoi(const picopal_char *s) {
|
||||
return (picopal_int32)atoi((const char *)s);
|
||||
}
|
||||
|
||||
picopal_int32 picopal_strcmp(const picopal_char *a, const picopal_char *b) {
|
||||
return (picopal_int32)strcmp((const char *)a, (const char *)b);
|
||||
}
|
||||
|
||||
picopal_int32 picopal_strncmp(const picopal_char *a, const picopal_char *b, picopal_objsize_t siz) {
|
||||
return (picopal_int32)strncmp((const char *)a, (const char *)b, (size_t) siz);
|
||||
}
|
||||
|
||||
picopal_objsize_t picopal_strlen(const picopal_char *s) {
|
||||
return (picopal_objsize_t)strlen((const char *)s);
|
||||
}
|
||||
|
||||
picopal_char *picopal_strchr(const picopal_char *s, picopal_char c) {
|
||||
return (picopal_char *)strchr((const char *)s, (int)c);
|
||||
}
|
||||
|
||||
picopal_char *picopal_strstr(const picopal_char *s, const picopal_char *substr) {
|
||||
return (picopal_char *)strstr((const char *)s, (const char *)substr);
|
||||
}
|
||||
|
||||
picopal_char *picopal_strcpy(picopal_char *d, const picopal_char *s) {
|
||||
return (picopal_char *)strcpy((char *)d, (const char *)s);
|
||||
}
|
||||
|
||||
picopal_char *picopal_strcat(picopal_char *dest, const picopal_char *src) {
|
||||
return (picopal_char *)strcat((char *)dest, (const char *)src);
|
||||
}
|
||||
|
||||
|
||||
/* copy src into dst, but make sure that dst is not accessed beyond its size 'siz' and is allways NULLC-terminated.
|
||||
* 'siz' is the number of bytes of the destination, including one byte for NULLC!
|
||||
* returns the full length of the input string, not including termination NULLC (strlen(src)).
|
||||
* the copy is successfull without truncation if picopal_strlcpy(dst,src,siz) < siz */
|
||||
picopal_objsize_t picopal_strlcpy(picopal_char *dst, const picopal_char *src, picopal_objsize_t siz)
|
||||
{
|
||||
picopal_char *d = dst;
|
||||
const picopal_char *s = src;
|
||||
picopal_objsize_t n = siz;
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0) {
|
||||
while (--n != 0) {
|
||||
if ((*(d++) = *(s++)) == NULLC) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NULLC and traverse rest of src */
|
||||
if (n == 0) {
|
||||
if (siz != 0) {
|
||||
*d = NULLC; /* NULLC-terminate dst */
|
||||
}
|
||||
while (*(s++)) {}
|
||||
;
|
||||
}
|
||||
|
||||
return(s - src - 1); /* count does not include NULLC */
|
||||
}
|
||||
|
||||
|
||||
picopal_int16 picopal_sprintf(picopal_char * dst, const picopal_char *fmt, ...)
|
||||
{
|
||||
picopal_int16 i;
|
||||
va_list args;
|
||||
|
||||
va_start(args, (char *)fmt);
|
||||
i = (picopal_int16)vsprintf((char *) dst, (const char *)fmt, args);
|
||||
va_end(args);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
picopal_objsize_t picopal_vslprintf(picopal_char * dst, picopal_objsize_t siz, const picopal_char *fmt, va_list args) {
|
||||
picopal_char buf[21];
|
||||
picopal_char *d = dst;
|
||||
const picopal_char *f = fmt;
|
||||
picopal_char * b;
|
||||
picopal_objsize_t len, nnew, n = siz;
|
||||
picopal_int32 ival;
|
||||
picopal_char cval;
|
||||
picopal_objsize_t i = 0;
|
||||
|
||||
if (!f) {
|
||||
f = (picopal_char *) "";
|
||||
}
|
||||
while (*f) {
|
||||
if (*f == '%') {
|
||||
switch (*(++f)) {
|
||||
case 'i':
|
||||
f++;
|
||||
ival = va_arg(args,int);
|
||||
picopal_sprintf(buf,(picopal_char *)"%i",ival);
|
||||
b = buf;
|
||||
break;
|
||||
case 'c':
|
||||
f++;
|
||||
cval = va_arg(args,int);
|
||||
picopal_sprintf(buf,(picopal_char *)"%c",cval);
|
||||
b = buf;
|
||||
break;
|
||||
case 's':
|
||||
f++;
|
||||
b = (picopal_char *) va_arg(args, char*);
|
||||
break;
|
||||
default:
|
||||
if (n > 0) {
|
||||
(*d++) = '%';
|
||||
n--;
|
||||
}
|
||||
i++;
|
||||
b = NULL;
|
||||
break;
|
||||
}
|
||||
if (b) {
|
||||
len = picopal_strlcpy(d,b,n); /* n1 is the actual length of sval */
|
||||
i += len;
|
||||
nnew = (n > len) ? n-len : 0; /* nnew is the new value of n */
|
||||
d += (n - nnew);
|
||||
n = nnew;
|
||||
}
|
||||
} else {
|
||||
if (n) {
|
||||
(*d++) = (*f);
|
||||
n--;
|
||||
}
|
||||
i++;
|
||||
f++;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
picopal_objsize_t picopal_slprintf(picopal_char * dst, picopal_objsize_t siz, const picopal_char *fmt, /*args*/ ...) {
|
||||
picopal_objsize_t i;
|
||||
va_list args;
|
||||
|
||||
va_start(args, (char *)fmt);
|
||||
i = picopal_vslprintf(dst, siz, fmt, args);
|
||||
va_end(args);
|
||||
return i;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* copies 'length' bytes from 'src' to 'dest'. (regions may be overlapping) no error checks! */
|
||||
void * picopal_mem_copy(const void * src, void * dst, picopal_objsize_t length)
|
||||
{
|
||||
return memmove(dst, src, (size_t) length);
|
||||
}
|
||||
|
||||
/* sets 'length' bytes starting at dest[0] to 'byte_val' */
|
||||
void * picopal_mem_set(void * dest, picopal_uint8 byte_val, picopal_objsize_t length)
|
||||
{
|
||||
return memset(dest, (int) byte_val, (size_t) length);
|
||||
}
|
||||
|
||||
/* *************************************************/
|
||||
/* fixed-point math */
|
||||
/* *************************************************/
|
||||
|
||||
/* *************************************************/
|
||||
/* transcendent math */
|
||||
/* *************************************************/
|
||||
|
||||
|
||||
picopal_double picopal_cos(const picopal_double cos_arg)
|
||||
{
|
||||
return (picopal_double) cos((double)cos_arg);
|
||||
}
|
||||
picopal_double picopal_sin(const picopal_double sin_arg)
|
||||
{
|
||||
return (picopal_double) sin((double) sin_arg);
|
||||
}
|
||||
picopal_double picopal_fabs(const picopal_double fabs_arg)
|
||||
{
|
||||
return (picopal_double) fabs((double) fabs_arg);
|
||||
}
|
||||
|
||||
|
||||
/* *************************************************/
|
||||
/* file access */
|
||||
/* *************************************************/
|
||||
#define PICOPAL_EOL '\n'
|
||||
|
||||
picopal_char picopal_eol(void)
|
||||
{
|
||||
return PICOPAL_EOL;
|
||||
}
|
||||
|
||||
/* 'fopen' opens the file with name 'filename'. Depending on
|
||||
'mode' :
|
||||
'PICOPAL_TEXT_READ' : Opens an existing text file for reading.
|
||||
The file is positioned at the beginning of the file.
|
||||
'PICOPAL_TEXT_WRITE' : Opens and truncates an existing file or creates a new
|
||||
text file for writing. The file is positioned at the
|
||||
beginning.
|
||||
'PICOPAL_BIN_READ' : Opens an existing binary file for reading.
|
||||
The file is positioned at the beginning of the file.
|
||||
'PICOPAL_BIN_WRITE' : Opens and truncates an existing file or creates a new
|
||||
binary file for writing. The file is positioned at the
|
||||
beginning.
|
||||
If the opening of the file is successful a file pointer is given
|
||||
back. Otherwise a NIL-File is given back.
|
||||
*/
|
||||
picopal_File picopal_fopen (picopal_char filename[], picopal_access_mode mode)
|
||||
{
|
||||
picopal_File res;
|
||||
|
||||
switch (mode) {
|
||||
case PICOPAL_TEXT_READ :
|
||||
res = (picopal_File) fopen((char *)filename, (char *)"r");
|
||||
break;
|
||||
case PICOPAL_TEXT_WRITE :
|
||||
res = (picopal_File) fopen((char *)filename, (char *)"w");
|
||||
break;
|
||||
case PICOPAL_BINARY_READ :
|
||||
res = (picopal_File) fopen((char *)filename, (char *)"rb");
|
||||
break;
|
||||
case PICOPAL_BINARY_WRITE :
|
||||
res = (picopal_File) fopen((char *)filename, (char *)"wb");
|
||||
break;
|
||||
default :
|
||||
res = (picopal_File) NULL;
|
||||
}
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
|
||||
picopal_File picopal_get_fnil (void)
|
||||
{
|
||||
return (picopal_File) NULL;
|
||||
}
|
||||
|
||||
|
||||
picopal_int8 picopal_is_fnil (picopal_File f)
|
||||
{
|
||||
return (NULL == f);
|
||||
}
|
||||
|
||||
pico_status_t picopal_fflush (picopal_File f)
|
||||
{
|
||||
return (0 == fflush((FILE *)f)) ? PICO_OK : PICO_EOF;
|
||||
}
|
||||
|
||||
|
||||
pico_status_t picopal_fclose (picopal_File f)
|
||||
{
|
||||
return (0 == fclose((FILE *)f)) ? PICO_OK : PICO_EOF;
|
||||
}
|
||||
|
||||
|
||||
|
||||
picopal_uint32 picopal_flength (picopal_File stream)
|
||||
{
|
||||
fpos_t fpos;
|
||||
picopal_int32 len;
|
||||
|
||||
fgetpos((FILE *)stream,&fpos);
|
||||
picopal_fseek(stream,0,SEEK_END);
|
||||
len = ftell((FILE *)stream);
|
||||
fsetpos((FILE *)stream,&fpos);
|
||||
clearerr((FILE *)stream);
|
||||
return len;
|
||||
|
||||
}
|
||||
|
||||
picopal_uint8 picopal_feof (picopal_File stream)
|
||||
{
|
||||
return (0 != feof((FILE *)stream));
|
||||
|
||||
}
|
||||
|
||||
pico_status_t picopal_fseek (picopal_File f, picopal_uint32 offset, picopal_int8 seekmode)
|
||||
{
|
||||
return (0 == fseek((FILE *)f, offset, seekmode)) ? PICO_OK : PICO_EOF;
|
||||
}
|
||||
|
||||
pico_status_t picopal_fget_char (picopal_File f, picopal_char * ch)
|
||||
{
|
||||
picopal_int16 res;
|
||||
|
||||
res = fgetc((FILE *)f);
|
||||
if (res >= 0) {
|
||||
*ch = (picopal_char) res;
|
||||
}
|
||||
else {
|
||||
*ch = '\0';
|
||||
}
|
||||
return (res >= 0) ? PICO_OK : PICO_EOF;
|
||||
}
|
||||
|
||||
picopal_objsize_t picopal_fread_bytes (picopal_File f, void * ptr, picopal_objsize_t objsize, picopal_uint32 nobj)
|
||||
{
|
||||
return (picopal_objsize_t) fread(ptr, objsize, nobj, (FILE *)f);
|
||||
}
|
||||
|
||||
picopal_objsize_t picopal_fwrite_bytes (picopal_File f, void * ptr, picopal_objsize_t objsize, picopal_uint32 nobj){ return (picopal_objsize_t) fwrite(ptr, objsize, nobj, (FILE *)f);}
|
||||
/* *************************************************/
|
||||
/* functions for debugging/testing purposes only */
|
||||
/* *************************************************/
|
||||
|
||||
void *picopal_mpr_alloc(picopal_objsize_t size)
|
||||
{
|
||||
#if PICO_PLATFORM == PICO_Windows
|
||||
return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
|
||||
#else
|
||||
/* not yet implemented for other platforms; corresponding
|
||||
function on UNIX systems is pvalloc */
|
||||
return NULL;
|
||||
#endif
|
||||
size = size; /* avoid warning "var not used in this function"*/
|
||||
|
||||
}
|
||||
|
||||
void picopal_mpr_free(void **p)
|
||||
{
|
||||
#if PICO_PLATFORM == PICO_Windows
|
||||
VirtualFree(*p, 0, MEM_RELEASE);
|
||||
#else
|
||||
/* not yet implemented for other platforms */
|
||||
#endif
|
||||
*p = NULL;
|
||||
}
|
||||
|
||||
pico_status_t picopal_mpr_protect(void *addr, picopal_objsize_t len, picopal_int16 prot)
|
||||
{
|
||||
pico_status_t status = PICO_OK;
|
||||
|
||||
#if PICO_PLATFORM == PICO_Windows
|
||||
DWORD dwNewProtect, dwOldProtect;
|
||||
dwNewProtect = PICOPAL_PROT_NONE;
|
||||
if (prot & PICOPAL_PROT_READ) {
|
||||
if (prot & PICOPAL_PROT_WRITE) {
|
||||
dwNewProtect = PAGE_READWRITE;
|
||||
} else {
|
||||
dwNewProtect = PAGE_READONLY;
|
||||
}
|
||||
} else if (prot & PICOPAL_PROT_WRITE) {
|
||||
/* under Windows write-only is not possible */
|
||||
dwNewProtect = PAGE_READWRITE;
|
||||
}
|
||||
if (!VirtualProtect(addr, len, dwNewProtect, &dwOldProtect)) {
|
||||
status = PICO_ERR_OTHER;
|
||||
}
|
||||
#else
|
||||
/* not yet implemented for other platforms */
|
||||
addr = addr; /* avoid warning "var not used in this function"*/
|
||||
len = len; /* avoid warning "var not used in this function"*/
|
||||
prot = prot; /* avoid warning "var not used in this function"*/
|
||||
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
/*
|
||||
* Reference:
|
||||
* A Fast, Compact Approximation of the Exponential Function by Nicol N. Schraudolph in Neural Computation, 11,853-862 (1999)
|
||||
* See also: http://www-h.eng.cam.ac.uk/help/tpl/programs/Matlab/mex.html
|
||||
*
|
||||
*/
|
||||
picopal_double picopal_quick_exp(const picopal_double y) {
|
||||
union {
|
||||
picopal_double d;
|
||||
struct {
|
||||
#if PICO_ENDIANNESS == ENDIANNESS_LITTLE /* little endian */
|
||||
picopal_int32 j,i;
|
||||
#else
|
||||
picopal_int32 i,j;
|
||||
#endif
|
||||
} n;
|
||||
|
||||
} _eco;
|
||||
_eco.n.i = (picopal_int32)(1512775.3951951856938297995605697f * y) + 1072632447;
|
||||
return _eco.d;
|
||||
}
|
||||
|
||||
|
||||
/* *************************************************/
|
||||
/* timer */
|
||||
/* *************************************************/
|
||||
|
||||
#if IMPLEMENT_TIMER
|
||||
|
||||
#define USEC_PER_SEC 1000000
|
||||
|
||||
typedef clock_t picopal_clock_t;
|
||||
|
||||
|
||||
#if USE_CLOCK
|
||||
picopal_clock_t startTime;
|
||||
#else
|
||||
int timerInit = 0;
|
||||
LARGE_INTEGER startTime;
|
||||
LARGE_INTEGER timerFreq;
|
||||
#endif
|
||||
|
||||
|
||||
picopal_clock_t picopal_clock(void)
|
||||
{
|
||||
return (picopal_clock_t)clock();
|
||||
}
|
||||
|
||||
#endif /* IMPLEMENT_TIMER */
|
||||
|
||||
void picopal_get_timer(picopal_uint32 * sec, picopal_uint32 * usec)
|
||||
{
|
||||
#if IMPLEMENT_TIMER
|
||||
#if USE_CLOCK
|
||||
picopal_clock_t dt;
|
||||
dt = picopal_clock() - startTime;
|
||||
*sec = dt / CLOCKS_PER_SEC;
|
||||
*usec = USEC_PER_SEC * (dt % CLOCKS_PER_SEC) / CLOCKS_PER_SEC;
|
||||
#else
|
||||
LARGE_INTEGER now;
|
||||
if (!timerInit) {
|
||||
QueryPerformanceFrequency(&timerFreq);
|
||||
timerInit = 1;
|
||||
}
|
||||
if (QueryPerformanceCounter(&now) && 0) {
|
||||
/*
|
||||
LONGLONG dt, tf;
|
||||
dt = now.QuadPart - GLOB(startTime).QuadPart;
|
||||
tf = GLOB(timerFreq).QuadPart;
|
||||
*sec = (unsigned int) (dt / tf);
|
||||
*usec = (unsigned int) (USEC_PER_SEC * (dt % tf) / tf);
|
||||
*/
|
||||
double dt, tf;
|
||||
dt = (double)(now.QuadPart - startTime.QuadPart);
|
||||
tf = (double)(timerFreq.QuadPart);
|
||||
*sec = (unsigned int) (dt /tf);
|
||||
*usec = (unsigned int) ((double)USEC_PER_SEC * (dt / tf)) % USEC_PER_SEC;
|
||||
} else {
|
||||
/* high freq counter not supported by system */
|
||||
DWORD dt;
|
||||
dt = GetTickCount() - startTime.LowPart;
|
||||
*sec = dt / 1000;
|
||||
*usec = 1000 * (dt % 1000);
|
||||
}
|
||||
#endif /* USE_CLOCK */
|
||||
#else
|
||||
*sec = 0;
|
||||
*usec = 0;
|
||||
#endif /* IMPLEMENT_TIMER */
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* End picopal.c */
|
||||
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picopal.h
|
||||
*
|
||||
* pico plattform abstraction layer
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @addtogroup picoos
|
||||
|
||||
* <b> Operating system Platform Specific implementation module </b>\n
|
||||
*
|
||||
*/
|
||||
#ifndef PICOPAL_H_
|
||||
#define PICOPAL_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include "picopltf.h"
|
||||
#include "picodefs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* *********************************************************/
|
||||
/* general defines and typedefs (used to be in picodefs.h) */
|
||||
/* *********************************************************/
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#define NULLC '\000'
|
||||
|
||||
|
||||
/* "strange" defines to switch variants... */
|
||||
#define PICOPAL_DIV_USE_INV 0
|
||||
|
||||
|
||||
/*---------------Externals-----------------------*/
|
||||
/* used by picocep*/
|
||||
#if defined(PICO_DEBUG)
|
||||
extern int numlongmult, numshortmult;
|
||||
#endif
|
||||
|
||||
|
||||
typedef signed int pico_status_t;
|
||||
|
||||
|
||||
/* unfortunately, ANSI-C uses eof for results and exceptional results .. */
|
||||
/* in the context of reading from a CharBuffer, eof means "no more
|
||||
input available FOR NOW" */
|
||||
|
||||
#define PICO_EOF (pico_status_t) -1
|
||||
|
||||
|
||||
/* *************************************************/
|
||||
/* constants */
|
||||
/* *************************************************/
|
||||
|
||||
|
||||
/* operating system identifications */
|
||||
#define PICOPAL_OS_NIL 0 /* just an unchangeable first value */
|
||||
#define PICOPAL_OS_WINDOWS 1
|
||||
/* ... */
|
||||
#define PICOPAL_OS_GENERIC 99 /* must always be the last value */
|
||||
|
||||
/* *************************************************/
|
||||
/* types */
|
||||
/* *************************************************/
|
||||
|
||||
typedef unsigned char picopal_uint8;
|
||||
typedef unsigned short picopal_uint16;
|
||||
typedef unsigned int picopal_uint32;
|
||||
|
||||
typedef signed char picopal_int8;
|
||||
typedef signed short picopal_int16;
|
||||
typedef signed int picopal_int32;
|
||||
|
||||
typedef float picopal_single;
|
||||
typedef double picopal_double;
|
||||
|
||||
typedef unsigned char picopal_char;
|
||||
|
||||
typedef unsigned char picopal_uchar;
|
||||
|
||||
typedef size_t picopal_objsize_t;
|
||||
typedef ptrdiff_t picopal_ptrdiff_t;
|
||||
|
||||
/* *************************************************/
|
||||
/* functions */
|
||||
/* *************************************************/
|
||||
|
||||
picopal_int32 picopal_atoi(const picopal_char *);
|
||||
|
||||
picopal_int32 picopal_strcmp(const picopal_char *, const picopal_char *);
|
||||
picopal_int32 picopal_strncmp(const picopal_char *a, const picopal_char *b, picopal_objsize_t siz);
|
||||
picopal_objsize_t picopal_strlen(const picopal_char *);
|
||||
picopal_char * picopal_strchr(const picopal_char *, picopal_char);
|
||||
picopal_char * picopal_strcpy(picopal_char *d, const picopal_char *s);
|
||||
picopal_char *picopal_strstr(const picopal_char *s, const picopal_char *substr);
|
||||
picopal_char *picopal_strcat(picopal_char *dest, const picopal_char *src);
|
||||
picopal_int16 picopal_sprintf(picopal_char * dst, const picopal_char *fmt, ...);
|
||||
|
||||
/* copies 'length' bytes from 'src' to 'dest'. (regions may be overlapping) no error checks! */
|
||||
void * picopal_mem_copy(const void * src, void * dst, picopal_objsize_t length);
|
||||
|
||||
/* sets 'length' bytes starting at dest[0] to 'byte_val' */
|
||||
void * picopal_mem_set(void * dest, picopal_uint8 byte_val, picopal_objsize_t length);
|
||||
|
||||
/* safe versions */
|
||||
picopal_objsize_t picopal_vslprintf(picopal_char * dst, picopal_objsize_t siz, const picopal_char *fmt, va_list args);
|
||||
picopal_objsize_t picopal_slprintf(picopal_char * dst, picopal_objsize_t siz, const picopal_char *fmt, /*args*/ ...);
|
||||
picopal_objsize_t picopal_strlcpy(picopal_char *dst, const picopal_char *src, picopal_objsize_t siz);
|
||||
|
||||
/*Fixed point computation*/
|
||||
/*
|
||||
picopal_int32 picopal_fixptdiv(picopal_int32 a, picopal_int32 b, picopal_uint8 bigpow);
|
||||
picopal_int32 picopal_fixptmult(picopal_int32 x, picopal_int32 y, picopal_uint8 bigpow);
|
||||
picopal_int32 picopal_fixptdivORinv(picopal_int32 a, picopal_int32 b, picopal_int32 invb, picopal_uint8 bigpow);
|
||||
picopal_int32 picopal_fixptmultdouble(picopal_int32 x, picopal_int32 y, picopal_uint8 bigpow);
|
||||
picopal_uint8 picopal_highestBit(picopal_int32 x);
|
||||
*/
|
||||
|
||||
/* *************************************************/
|
||||
/* math */
|
||||
/* *************************************************/
|
||||
|
||||
picopal_double picopal_cos (const picopal_double cos_arg);
|
||||
picopal_double picopal_sin (const picopal_double sin_arg);
|
||||
picopal_double picopal_fabs (const picopal_double fabs_arg);
|
||||
|
||||
|
||||
|
||||
|
||||
/* *************************************************/
|
||||
/* file access */
|
||||
/* *************************************************/
|
||||
|
||||
extern picopal_char picopal_eol(void);
|
||||
|
||||
#define picopal_FILE FILE
|
||||
|
||||
|
||||
/* seek modes to be used with the 'FSeek' procedure */
|
||||
#define PICOPAL_SEEK_SET 0 /* absolut seek position */
|
||||
#define PICOPAL_SEEK_CUR 1 /* relative to current */
|
||||
#define PICOPAL_SEEK_END 2 /* relative to the end of the file */
|
||||
|
||||
|
||||
typedef enum {PICOPAL_BINARY_READ, PICOPAL_BINARY_WRITE, PICOPAL_TEXT_READ, PICOPAL_TEXT_WRITE} picopal_access_mode;
|
||||
|
||||
typedef picopal_FILE * picopal_File;
|
||||
|
||||
extern picopal_File picopal_fopen (picopal_char fileName[], picopal_access_mode mode);
|
||||
/* 'FOpen' opens the file with name 'filename'. Depending on
|
||||
'mode' :
|
||||
'TextRead' : Opens an existing text file for reading.
|
||||
The file is positioned at the beginning of the file.
|
||||
'TextWrite' : Opens and truncates an existing file or creates a new
|
||||
text file for writing. The file is positioned at the
|
||||
beginning.
|
||||
'BinaryRead' : Opens an existing binary file for reading.
|
||||
The file is positioned at the beginning of the file.
|
||||
'BinaryWrite' : Opens and truncates an existing file or creates a new
|
||||
binary file for writing. The file is positioned at the
|
||||
beginning.
|
||||
If the opening of the file is successful a file pointer is given
|
||||
back. Otherwise a NIL-File is given back.
|
||||
*/
|
||||
|
||||
|
||||
extern picopal_File picopal_get_fnil (void);
|
||||
|
||||
|
||||
extern picopal_int8 picopal_is_fnil (picopal_File f);
|
||||
|
||||
|
||||
extern pico_status_t picopal_fclose (picopal_File f);
|
||||
|
||||
|
||||
extern picopal_uint32 picopal_flength (picopal_File f);
|
||||
|
||||
|
||||
extern picopal_uint8 picopal_feof (picopal_File f);
|
||||
|
||||
|
||||
extern pico_status_t picopal_fseek (picopal_File f, picopal_uint32 offset, picopal_int8 seekmode);
|
||||
|
||||
|
||||
extern pico_status_t picopal_fget_char (picopal_File f, picopal_char * ch);
|
||||
|
||||
|
||||
extern picopal_objsize_t picopal_fread_bytes (picopal_File f, void * ptr, picopal_objsize_t objsize, picopal_uint32 nobj);
|
||||
|
||||
extern picopal_objsize_t picopal_fwrite_bytes (picopal_File f, void * ptr, picopal_objsize_t objsize, picopal_uint32 nobj);
|
||||
|
||||
|
||||
extern pico_status_t picopal_fflush (picopal_File f);
|
||||
|
||||
/*
|
||||
extern pico_status_t picopal_fput_char (picopal_File f, picopal_char ch);
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
extern pico_status_t picopal_remove (picopal_char filename[]);
|
||||
|
||||
|
||||
extern pico_status_t picopal_rename (picopal_char oldname[], picopal_char newname[]);
|
||||
|
||||
*/
|
||||
|
||||
/* *************************************************/
|
||||
/* functions for debugging/testing purposes only */
|
||||
/* *************************************************/
|
||||
|
||||
/**
|
||||
* Returns a pointer to a newly allocated chunk of 'size' bytes, aligned
|
||||
* to the system page size.
|
||||
* Memory allocated by this routine may be protected by calling function
|
||||
* picopal_mrp_protect().
|
||||
*/
|
||||
void *picopal_mpr_alloc(picopal_objsize_t size);
|
||||
|
||||
/**
|
||||
* Releases the chunk of memory pointed to by '*p'. 'p' must be previously
|
||||
* allocated by a call to picopal_mpr_alloc().
|
||||
*/
|
||||
void picopal_mpr_free(void **p);
|
||||
|
||||
#define PICOPAL_PROT_NONE 0 /* the memory cannot be accessed at all */
|
||||
#define PICOPAL_PROT_READ 1 /* the memory can be read */
|
||||
#define PICOPAL_PROT_WRITE 2 /* the memory can be written to */
|
||||
|
||||
/**
|
||||
* Specifies the desired protection 'prot' for the memory page(s) containing
|
||||
* part or all of the interval [addr, addr+len-1]. If an access is disallowed
|
||||
* by the protection given it, the program receives a SIGSEGV.
|
||||
*/
|
||||
pico_status_t picopal_mpr_protect(void *addr, picopal_objsize_t len, picopal_int16 prot);
|
||||
|
||||
/* Fast, Compact Approximation of the Exponential Function */
|
||||
picopal_double picopal_quick_exp(const picopal_double y);
|
||||
|
||||
/* *************************************************/
|
||||
/* types functions for time measurement */
|
||||
/* *************************************************/
|
||||
|
||||
extern void picopal_get_timer(picopal_uint32 * sec, picopal_uint32 * usec);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*PICOPAL_H_*/
|
||||
+4810
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picopam.h
|
||||
*
|
||||
* Phonetic to Acoustic Mapping PU - Header file
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @addtogroup picopam
|
||||
|
||||
* <b> Phonetic to acoustic mapping module </b>\n
|
||||
*
|
||||
* This module is responsible for mapping the phonetic domain features generated from text analysis
|
||||
* into parametric representations suitable for signal generation. As such it is the interface
|
||||
* between text analysis and signal generation
|
||||
*
|
||||
* Most the processing of PAM is logically splittable as follows
|
||||
* - building a suitable symbolic feature vector set for the sentence
|
||||
* - Feeding Decision Trees with the symbolic seqence vector set
|
||||
* - Colecting the parametric output of the Decision trees into suitable items to be sent to following PU's
|
||||
*
|
||||
* To perform the decision tree feeding and output collection the PU uses an internal buffer. This
|
||||
* buffer is used several times with different meanings.
|
||||
* - While building the symbolic feature vector set for the sentence this data structure stores syllable relevant data.
|
||||
* The corresponding phonetic data is stored outside as a single string of phonetic id's for all the sentence.
|
||||
* - While feeding the decision trees the data structure is used to represent data for phonemes of the syllable
|
||||
* - Addiotional data strucures are mantained to temporarily store items not pertaining to the PAM processing, for later resynchronization
|
||||
*
|
||||
* A quite detailed description of PAM processing is in the Know How section of the repository.
|
||||
*/
|
||||
|
||||
#ifndef PICOPAM_H_
|
||||
#define PICOPAM_H_
|
||||
|
||||
#include "picodata.h"
|
||||
#include "picokdt.h"
|
||||
#include "picokpdf.h"
|
||||
#include "picoktab.h"
|
||||
#include "picokdbg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
Service routines
|
||||
------------------------------------------------------------------*/
|
||||
picodata_ProcessingUnit picopam_newPamUnit(
|
||||
picoos_MemoryManager mm, picoos_Common common,
|
||||
picodata_CharBuffer cbIn, picodata_CharBuffer cbOut,
|
||||
picorsrc_Voice voice);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /*PICOPAM_H_*/
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picopltf.h
|
||||
*
|
||||
* Header file (only) to define platform symbols.
|
||||
*
|
||||
* Refer to http://predef.sourceforge.net/ for a comprehensive list
|
||||
* of pre-defined C/C++ compiler macros.
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*/
|
||||
|
||||
#if !defined(__PICOPLTF_H__)
|
||||
#define __PICOPLTF_H__
|
||||
|
||||
#define ENDIANNESS_BIG 1
|
||||
#define ENDIANNESS_LITTLE 2
|
||||
|
||||
/* * platform identifiers ***/
|
||||
#define PICO_Windows 1 /* Windows */
|
||||
#define PICO_MacOSX 5 /* Macintosh OS X */
|
||||
#define PICO_Linux 7 /* Linux */
|
||||
|
||||
#define PICO_GENERIC 99 /* Generic */
|
||||
|
||||
/* * definition of current platform ***/
|
||||
#if !defined(PICO_PLATFORM)
|
||||
#if defined(_WIN32)
|
||||
#define PICO_PLATFORM PICO_Windows
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
#define PICO_PLATFORM PICO_MacOSX
|
||||
#elif defined(linux) || defined(__linux__) || defined(__linux)
|
||||
#define PICO_PLATFORM PICO_Linux
|
||||
#else
|
||||
#define PICO_PLATFORM PICO_GENERIC
|
||||
#endif
|
||||
#endif /* !defined(PICO_PLATFORM) */
|
||||
|
||||
|
||||
/* * symbol PICO_PLATFORM_STRING to define platform as string ***/
|
||||
#if (PICO_PLATFORM == PICO_Windows)
|
||||
#define PICO_PLATFORM_STRING "Windows"
|
||||
#elif (PICO_PLATFORM == PICO_MacOSX)
|
||||
#define PICO_PLATFORM_STRING "MacOSX"
|
||||
#elif (PICO_PLATFORM == PICO_Linux)
|
||||
#define PICO_PLATFORM_STRING "Linux"
|
||||
#elif (PICO_PLATFORM == PICO_GENERIC)
|
||||
#define PICO_PLATFORM_STRING "UnknownPlatform"
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#define __BYTE_ORDER _BYTE_ORDER
|
||||
#define __BIG_ENDIAN _BIG_ENDIAN
|
||||
#include <sys/endian.h>
|
||||
#else
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define PICO_ENDIANNESS ENDIANNESS_BIG
|
||||
#else
|
||||
#define PICO_ENDIANNESS ENDIANNESS_LITTLE
|
||||
#endif
|
||||
|
||||
#endif /* !defined(__PICOPLTF_H__) */
|
||||
+3555
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picopr.h
|
||||
*
|
||||
* text preprocessor PU - include file
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @addtogroup picopr
|
||||
*
|
||||
* <b> Text Pre Processing module </b>\n
|
||||
*
|
||||
*/
|
||||
#ifndef PICOPR_H_
|
||||
#define PICOPR_H_
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picodata.h"
|
||||
#include "picorsrc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
picodata_ProcessingUnit picopr_newPreprocUnit(
|
||||
picoos_MemoryManager mm,
|
||||
picoos_Common common,
|
||||
picodata_CharBuffer cbIn,
|
||||
picodata_CharBuffer cbOut,
|
||||
picorsrc_Voice voice);
|
||||
|
||||
#define PICOPR_OUTBUF_SIZE 256
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*PICOPR_H_*/
|
||||
+1028
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picorsrc.h
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @addtogroup picorsrc
|
||||
*
|
||||
* <b> Pico Resource Management module </b>\n
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PICORSRC_H_
|
||||
#define PICORSRC_H_
|
||||
|
||||
#include "picodefs.h"
|
||||
#include "picoos.h"
|
||||
#include "picoknow.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define PICORSRC_MAX_RSRC_NAME_SIZ PICO_MAX_RESOURCE_NAME_SIZE /* including terminating NULLC */
|
||||
|
||||
#define PICORSRC_MAX_NUM_VOICES 64
|
||||
|
||||
/* size of kb array of a voice */
|
||||
#define PICORSRC_KB_ARRAY_SIZE 64
|
||||
|
||||
typedef picoos_char picorsrc_resource_name_t[PICORSRC_MAX_RSRC_NAME_SIZ];
|
||||
|
||||
typedef enum picorsrc_resource_type {
|
||||
PICORSRC_TYPE_NULL,
|
||||
PICORSRC_TYPE_TEXTANA,
|
||||
PICORSRC_TYPE_SIGGEN,
|
||||
PICORSRC_TYPE_USER_LEX,
|
||||
PICORSRC_TYPE_USER_PREPROC,
|
||||
PICORSRC_TYPE_OTHER
|
||||
} picorsrc_resource_type_t;
|
||||
|
||||
|
||||
#define PICORSRC_FIELD_VALUE_TEXTANA (picoos_char *) "TEXTANA"
|
||||
#define PICORSRC_FIELD_VALUE_SIGGEN (picoos_char *) "SIGGEN"
|
||||
#define PICORSRC_FIELD_VALUE_USERLEX (picoos_char *) "USERLEX"
|
||||
#define PICORSRC_FIELD_VALUE_USERTPP (picoos_char *) "USERTPP"
|
||||
|
||||
|
||||
|
||||
typedef struct picorsrc_resource_manager * picorsrc_ResourceManager;
|
||||
typedef struct picorsrc_voice * picorsrc_Voice;
|
||||
typedef struct picorsrc_resource * picorsrc_Resource;
|
||||
|
||||
|
||||
/* **************************************************************************
|
||||
*
|
||||
* file name extensions
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define PICO_BIN_EXTENSION ".bin"
|
||||
#define PICO_INPLACE_EXTENSION ".inp"
|
||||
|
||||
|
||||
|
||||
/* **************************************************************************
|
||||
*
|
||||
* construct/destruct resource manager
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* create resource manager, given a config file name (or default name, if empty) */
|
||||
|
||||
picorsrc_ResourceManager picorsrc_newResourceManager(picoos_MemoryManager mm, picoos_Common common /* , picoos_char * configFile */);
|
||||
|
||||
void picorsrc_disposeResourceManager(picoos_MemoryManager mm, picorsrc_ResourceManager * this);
|
||||
|
||||
|
||||
/* **************************************************************************
|
||||
*
|
||||
* resources
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* Returns non-zero if 'resource' is a valid resource handle, zero otherwise.
|
||||
*/
|
||||
picoos_int16 picoctrl_isValidResourceHandle(picorsrc_Resource resource);
|
||||
|
||||
/* load resource file. the type of resource file, magic numbers, checksum etc. are in the header, then follows the directory
|
||||
* (with fixed structure per resource type), then the knowledge bases themselves (as byte streams) */
|
||||
pico_status_t picorsrc_loadResource(picorsrc_ResourceManager this,
|
||||
picoos_char * fileName, picorsrc_Resource * resource);
|
||||
|
||||
/* unload resource file. (warn if resource file is busy) */
|
||||
pico_status_t picorsrc_unloadResource(picorsrc_ResourceManager this, picorsrc_Resource * rsrc);
|
||||
|
||||
|
||||
pico_status_t picorsrc_createDefaultResource(picorsrc_ResourceManager this /*,
|
||||
picorsrc_Resource * resource */);
|
||||
|
||||
|
||||
pico_status_t picorsrc_rsrcGetName(picorsrc_Resource resource,
|
||||
picoos_char * name, picoos_uint32 maxlen);
|
||||
|
||||
/* **************************************************************************
|
||||
*
|
||||
* voice definitions
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
pico_status_t picorsrc_createVoiceDefinition(picorsrc_ResourceManager this,
|
||||
picoos_char * voiceName);
|
||||
|
||||
|
||||
pico_status_t picorsrc_releaseVoiceDefinition(picorsrc_ResourceManager this,
|
||||
picoos_char * voiceName);
|
||||
|
||||
pico_status_t picorsrc_addResourceToVoiceDefinition(picorsrc_ResourceManager this,
|
||||
picoos_char * voiceName, picoos_char * resourceName);
|
||||
|
||||
/* **************************************************************************
|
||||
*
|
||||
* voices
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/** object : Voice
|
||||
* shortcut : voice
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct picorsrc_voice {
|
||||
|
||||
picorsrc_Voice next;
|
||||
|
||||
picoknow_KnowledgeBase kbArray[PICORSRC_KB_ARRAY_SIZE];
|
||||
|
||||
picoos_uint8 numResources;
|
||||
|
||||
picorsrc_Resource resourceArray[PICO_MAX_NUM_RSRC_PER_VOICE];
|
||||
|
||||
|
||||
} picorsrc_voice_t;
|
||||
|
||||
|
||||
|
||||
/* create voice, given a voice name. the corresponding lock counts are incremented */
|
||||
pico_status_t picorsrc_createVoice(picorsrc_ResourceManager this, const picoos_char * voiceName, picorsrc_Voice * voice);
|
||||
|
||||
/* dispose voice. the corresponding lock counts are decremented. */
|
||||
pico_status_t picorsrc_releaseVoice(picorsrc_ResourceManager this, picorsrc_Voice * voice);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /*PICORSRC_H_*/
|
||||
+1743
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picosa.h
|
||||
*
|
||||
* sentence analysis - POS disambiguation - Include file
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup picosa
|
||||
* ---------------------------------------------------\n
|
||||
* <b> Pico Sentence analysis </b>\n
|
||||
* ---------------------------------------------------\n
|
||||
*
|
||||
itemtype, iteminfo1, iteminfo2, content -> TYPE(INFO1,INFO2)content
|
||||
in the following
|
||||
|
||||
items input
|
||||
===========
|
||||
|
||||
processed by sa (POS disambiguation):
|
||||
- WORDGRAPH(POSes,NA)graph
|
||||
- WORDINDEX(POSes,NA)POS|1ind1...POSN|indN
|
||||
- CMD(PICODATA_ITEMINFO1_CMD_FLUSH,PICODATA_ITEMINFO2_NA)
|
||||
|
||||
processed by sa (Phrasing, Accentuation):
|
||||
- PUNC(PUNCtype,PUNCsubtype)
|
||||
|
||||
unprocessed:
|
||||
- all other item types are forwarded through the PU without modification:
|
||||
CMD
|
||||
|
||||
|
||||
minimal input size (before processing starts)
|
||||
==================
|
||||
|
||||
processing (POS disambiguation, g2p, lexind, phrasing, accentuation)
|
||||
is possible with
|
||||
|
||||
- one punctuation-phrase, consisting of a sequence (see below for
|
||||
limits) of items terminated by a PUNC item.
|
||||
|
||||
(possible but not implemented: as long as the internal buffer is
|
||||
empty, non-processed item types can be processed immediately)
|
||||
|
||||
Ensuring terminal PUNC item:
|
||||
- when reading items from the external buffer a CMD(...FLUSH...) is
|
||||
converted to a PUNC(...FLUSH...) item
|
||||
- If needed, a PUNC(PHRASE) is artificially added to ensure a phrase
|
||||
fits in the PUs memory and processing can start.
|
||||
|
||||
|
||||
items processed and output
|
||||
==========================
|
||||
|
||||
precondition:
|
||||
CMD(...FLUSH...) already converted to PUNC(...FLUSH...) and trailing
|
||||
PUNC item enforced if necessary.
|
||||
|
||||
----
|
||||
1. PROCESS_POSD: processing input WORDGRAPH or WORDINDEX items, after
|
||||
POS disambiguation (POSes -> POS), results in a sequence of:
|
||||
|
||||
-> WORDGRAPH(POS,NA)graph
|
||||
-> WORDINDEX(POS,NA)POS|ind
|
||||
|
||||
----
|
||||
2. PROCESS_WPHO: then, after lex-index lookup and G2P in a
|
||||
sequence of:
|
||||
|
||||
-> WORDPHON(POS,NA)phon
|
||||
|
||||
(phon containing primary and secondary word-level stress)
|
||||
|
||||
----
|
||||
3. PROCESS_PHR: then, after processing these WORDPHON items,
|
||||
together with the trailing PUNC item results in:
|
||||
|
||||
-> BOUND(BOUNDstrength,BOUNDtype)
|
||||
|
||||
being added in the sequence of WORDPHON (respectively inserted instead
|
||||
of the PUNC). All PUNC, incl PUNC(...FLUSH...) now gone.
|
||||
|
||||
----
|
||||
4. PROCESS_ACC: then, after processing the WORDPHON and BOUND items
|
||||
results in:
|
||||
|
||||
-> WORDPHON(POS,ACC)phon
|
||||
|
||||
A postprocessing step of accentuation is hard-coded in the
|
||||
accentuation module: In case the whole word does not have any stress
|
||||
at all (primary or secondary or both) then do the following mapping:
|
||||
|
||||
ACC0 nostress -> ACC0
|
||||
ACC1 nostress -> ACC3
|
||||
ACC2 nostress -> ACC3
|
||||
ACC3 nostress -> ACC3
|
||||
|
||||
----
|
||||
- POS
|
||||
a single, unambiguous POS
|
||||
|
||||
cf. picodata.h for
|
||||
- ACC (sentence-level accent (aka prominence)) %d
|
||||
PICODATA_ACC0
|
||||
PICODATA_ACC1
|
||||
PICODATA_ACC2 (<- maybe mapped to ACC1, ie. no ACC2 in output)
|
||||
PICODATA_ACC3
|
||||
|
||||
- BOUNDstrength %d
|
||||
PICODATA_ITEMINFO1_BOUND_SBEG (at sentence start)
|
||||
PICODATA_ITEMINFO1_BOUND_SEND (at sentence end)
|
||||
PICODATA_ITEMINFO1_BOUND_TERM (replaces a flush)
|
||||
PICODATA_ITEMINFO1_BOUND_PHR1 (primary boundary)
|
||||
PICODATA_ITEMINFO1_BOUND_PHR2 (short break)
|
||||
PICODATA_ITEMINFO1_BOUND_PHR3 (secondary phrase boundary, no break)
|
||||
PICODATA_ITEMINFO1_BOUND_PHR0 (no break, not produced by sa, not existing
|
||||
BOUND in item sequence equals PHR0 bound strength)
|
||||
|
||||
- BOUNDtype (created in sa base on punctuation, indicates type of phrase
|
||||
following the boundary) %d
|
||||
PICODATA_ITEMINFO2_BOUNDTYPE_P
|
||||
PICODATA_ITEMINFO2_BOUNDTYPE_T
|
||||
PICODATA_ITEMINFO2_BOUNDTYPE_Q
|
||||
PICODATA_ITEMINFO2_BOUNDTYPE_E
|
||||
|
||||
|
||||
output sequence (without CMDs):
|
||||
|
||||
<output> = { BOUND(BOUND_SBEG,PHRASEtype) <sentence> BOUND(BOUND_SEND,..)} BOUND(BOUND_TERM,..)
|
||||
|
||||
|
||||
<sentence> = <phrase> { BOUND(BOUND_PHR1|2|3,BOUNDtype) <phrase> }
|
||||
|
||||
<phrase> = WORDPHON(POS,ACC)phon { WORDPHON(POS,ACC)phon }
|
||||
|
||||
|
||||
Done in later PU: mapping ACC & word-level stress to syllable accent value
|
||||
ACC0 prim -> 0
|
||||
ACC1 prim -> 1
|
||||
ACC2 prim -> 2
|
||||
ACC3 prim -> 3
|
||||
ACC0 sec -> 0
|
||||
ACC1 sec -> 4
|
||||
ACC2 sec -> 4
|
||||
ACC3 sec -> 4
|
||||
|
||||
|
||||
other limitations
|
||||
=================
|
||||
|
||||
- item size: header plus len=256 (valid for Pico in general)
|
||||
- see defines below for max nr of items. Item heads plus ref. to contents
|
||||
buffer are stored in array with fixed size elements. Two restrictions:
|
||||
- MAXNR_HEADX (max nr elements==items in headx array)
|
||||
- CONTENTSSIZE (max size of all contents together
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PICOSA_H_
|
||||
#define PICOSA_H_
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picodata.h"
|
||||
#include "picorsrc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* nr item restriction: maximum number of extended item heads in headx */
|
||||
#define PICOSA_MAXNR_HEADX 60
|
||||
/* nr item restriction: maximum size of all item contents together in cont */
|
||||
#define PICOSA_MAXSIZE_CBUF 7680
|
||||
|
||||
/* maximum length of an item incl. head for input GetItem buffer */
|
||||
#define PICOSA_MAXITEMSIZE 260
|
||||
|
||||
|
||||
picodata_ProcessingUnit picosa_newSentAnaUnit(
|
||||
picoos_MemoryManager mm,
|
||||
picoos_Common common,
|
||||
picodata_CharBuffer cbIn,
|
||||
picodata_CharBuffer cbOut,
|
||||
picorsrc_Voice voice);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*PICOSA_H_*/
|
||||
+1287
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picosig.h
|
||||
*
|
||||
* Signal Generation PU - Header file
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @addtogroup picosig
|
||||
*
|
||||
* <b> Pico Signal Generation module </b>\n
|
||||
*
|
||||
* Pico Sig is the PU that makes the parametric representation produce a speech signal.
|
||||
* The PU receives parametric vectors and translates them into signal vectors.
|
||||
* Most of the processing is based on this 1 to 1 relationship between input and output vectors.
|
||||
*
|
||||
* NOTE : "picosig" includes logically "picosig2" module, that is the DSP implementation of the signal generation.
|
||||
*/
|
||||
|
||||
#ifndef PICOSIG_H_
|
||||
#define PICOSIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
/* *******************************************************************************
|
||||
* items related to the generic interface
|
||||
********************************************************************************/
|
||||
picodata_ProcessingUnit picosig_newSigUnit(
|
||||
picoos_MemoryManager mm,
|
||||
picoos_Common common,
|
||||
picodata_CharBuffer cbIn,
|
||||
picodata_CharBuffer cbOut,
|
||||
picorsrc_Voice voice);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*PICOSIG_H_*/
|
||||
+4105
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picosig2.h
|
||||
*
|
||||
* Signal Generation PU - Internal functions - header file
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PICOSIG2_H_
|
||||
#define PICOSIG2_H_
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picodsp.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------
|
||||
// Name : sig_innerobj
|
||||
// Function: innerobject definition for the sig processing
|
||||
// Shortcut: sig
|
||||
//---------------------------------------------------------*/
|
||||
typedef struct sig_innerobj
|
||||
{
|
||||
|
||||
/*-----------------------Definition of the local storage for this PU--------*/
|
||||
picoos_int16 *idx_vect1; /*reserved for bit reversal tables*/
|
||||
picoos_int16 *idx_vect2; /*reserved for table lookup "A" vector*/
|
||||
picoos_int16 *idx_vect4; /*reserved for max peak index arrax in pchip*/
|
||||
picoos_int16 *idx_vect5; /*reserved for min index arrax in sigana_singleIMF*/
|
||||
picoos_int16 *idx_vect6; /*reserved for max index arrax in sigana_singleIMF*/
|
||||
picoos_int16 *idx_vect7; /*reserved for dispersed phase */
|
||||
picoos_int16 *idx_vect8; /*reserved for LocV*/
|
||||
picoos_int16 *idx_vect9; /*reserved for LocU*/
|
||||
|
||||
picoos_int32 *int_vec22; /*reserved for normalized hanning window - fixed point */
|
||||
picoos_int32 *int_vec23; /*reserved for impresp - fixed point */
|
||||
picoos_int32 *int_vec24; /*reserved for impresp - fixed point */
|
||||
picoos_int32 *int_vec25; /*reserved for window - fixed point */
|
||||
picoos_int32 *int_vec26; /*reserved for wavBuf - fixed point */
|
||||
picoos_int32 *int_vec28; /*reserved for cepstral vectors input - fixed point */
|
||||
picoos_int32 *int_vec29; /*reserved for cepstral vectors input - fixed point */
|
||||
picoos_int32 *int_vec38; /*reserved for cepstral vectors input - fixed point */
|
||||
picoos_int32 *int_vec30; /*reserved for cepstral vectors input - fixed point */
|
||||
picoos_int32 *int_vec31; /*reserved for cepstral vectors input - fixed point */
|
||||
|
||||
picoos_int32 *int_vec32; /*reserved for cepstral vectors input - fixed point */
|
||||
picoos_int32 *int_vec33; /*reserved for cepstral vectors input - fixed point */
|
||||
|
||||
picoos_int32 *int_vec34; /* reserved for sin table- fixed point */
|
||||
picoos_int32 *int_vec35; /* reserved for cos table - fixed point */
|
||||
picoos_int32 *int_vec36; /* reserved for currently used sin table- fixed point */
|
||||
picoos_int32 *int_vec37; /* reserved for currently used cos table - fixed point */
|
||||
|
||||
picoos_int32 *int_vec39; /* reserved for ang - fixed point */
|
||||
picoos_int32 *int_vec40; /* reserved for cos table - fixed point */
|
||||
|
||||
picoos_int32 *int_vec41[CEPST_BUFF_SIZE]; /*reserved for phase smoothing - cepstrum buffers */
|
||||
picoos_int32 *int_vec42[PHASE_BUFF_SIZE]; /*reserved for phase smoothing - phase buffers */
|
||||
|
||||
picoos_int16 idx_vect10[CEPST_BUFF_SIZE]; /*reserved for pitch value buffering before phase smoothing*/
|
||||
picoos_int16 idx_vect11[CEPST_BUFF_SIZE]; /*reserved for phonetic value bufferingid before phase smoothing*/
|
||||
picoos_int16 idx_vect12[CEPST_BUFF_SIZE]; /*reserved for voicing value bufferingbefore phase smoothing*/
|
||||
picoos_int16 idx_vect13[CEPST_BUFF_SIZE]; /*reserved for unrectified pitch value bufferingbefore phase smoothing*/
|
||||
picoos_int16 idx_vect14[PHASE_BUFF_SIZE]; /*reserved for vox_bnd value buffering before phase smoothing*/
|
||||
|
||||
picoos_int32 *sig_vec1;
|
||||
|
||||
picoos_single bvalue1; /*reserved for warp*/
|
||||
picoos_int32 ibvalue2; /*reserved for voxbnd*/
|
||||
picoos_int32 ibvalue3; /*reserved for voxbnd2*/
|
||||
picoos_single bvalue4; /*reserved for E*/
|
||||
picoos_single bvalue5; /*reserved for F0*/
|
||||
picoos_single bvalue6; /*reserved for sMod*/
|
||||
|
||||
picoos_single bvalue7; /*reserved for voicing*/
|
||||
picoos_single bvalue8; /*reserved for unrectified pitch*/
|
||||
|
||||
picoos_int16 ivalue1; /*reserved for m1,ceporder*/
|
||||
picoos_int16 ivalue2; /*reserved for m2,fftorder,windowlen*/
|
||||
picoos_int16 ivalue3; /*reserved for fftorder/2*/
|
||||
picoos_int16 ivalue4; /*reserved for framelen, displacement*/
|
||||
picoos_int16 ivalue5; /*reserved for voiced*/
|
||||
picoos_int16 ivalue6; /*reserved for generic result code*/
|
||||
picoos_int16 ivalue7; /*reserved for i*/
|
||||
picoos_int16 ivalue8; /*reserved for j*/
|
||||
picoos_int16 ivalue9; /*reserved for hop*/
|
||||
picoos_int16 ivalue10; /*reserved for nextPeak*/
|
||||
picoos_int16 ivalue11; /*reserved for nFrame*/
|
||||
picoos_int16 ivalue12; /*reserved for raw*/
|
||||
picoos_int16 ivalue13; /*reserved for hts engine flag*/
|
||||
picoos_int16 ivalue14; /*reserved for ph id*/
|
||||
picoos_int16 ivalue15; /*reserved for Voiced*/
|
||||
picoos_int16 ivalue16; /*reserved for prevVoiced*/
|
||||
picoos_int16 ivalue17; /*reserved for nV (size of LocV)*/
|
||||
picoos_int16 ivalue18; /*reserved for nU (size of LocU)*/
|
||||
|
||||
picoos_int16 ivalue19; /*reserved for voicTrans*/
|
||||
|
||||
picoos_int16 ivalue20; /*reserved for n_availabe index*/
|
||||
|
||||
picoos_int32 lvalue1; /*reserved for sampling rate*/
|
||||
picoos_int32 lvalue2; /*reserved for VCutoff*/
|
||||
picoos_int32 lvalue3; /*reserved for UVCutoff*/
|
||||
picoos_int32 lvalue4; /*reserved for fMax */
|
||||
|
||||
picoos_int32 iRand; /*reserved for phase random table poointer ())*/
|
||||
|
||||
} sig_innerobj_t;
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
Exported (to picosig.c) Service routines :
|
||||
routine name and I/O parameters are to be maintained for PICO compatibility!!
|
||||
------------------------------------------------------------------*/
|
||||
extern pico_status_t sigAllocate(picoos_MemoryManager mm,
|
||||
sig_innerobj_t *sig_inObj);
|
||||
extern void sigDeallocate(picoos_MemoryManager mm, sig_innerobj_t *sig_inObj);
|
||||
extern void sigDspInitialize(sig_innerobj_t *sig_inObj, picoos_int32 resetMode);
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
Exported (to picosig.c) Processing routines :
|
||||
routine number, name and content can be changed. unique I/O parameter should be "sig"
|
||||
------------------------------------------------------------------*/
|
||||
extern void mel_2_lin_init(sig_innerobj_t *sig_inObj);
|
||||
extern void save_transition_frame(sig_innerobj_t *sig_inObj);
|
||||
extern void mel_2_lin_init(sig_innerobj_t *sig_inObj);
|
||||
extern void post_filter_init(sig_innerobj_t *sig_inObj);
|
||||
extern void mel_2_lin_lookup(sig_innerobj_t *sig_inObj, picoos_uint32 mgc);
|
||||
extern void post_filter(sig_innerobj_t *sig_inObj);
|
||||
extern void phase_spec2(sig_innerobj_t *sig_inObj);
|
||||
extern void env_spec(sig_innerobj_t *sig_inObj);
|
||||
extern void save_transition_frame(sig_innerobj_t *sig_inObj);
|
||||
extern void td_psola2(sig_innerobj_t *sig_inObj);
|
||||
extern void impulse_response(sig_innerobj_t *sig_inObj);
|
||||
extern void overlap_add(sig_innerobj_t *sig_inObj);
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* symbolic vs area assignements
|
||||
* -------------------------------------------------------------------*/
|
||||
#define WavBuff_p int_vec26 /*output is Wav buffer (2*FFTSize)*/
|
||||
#define window_p int_vec25 /*window function (hanning) */
|
||||
#define ImpResp_p int_vec23 /*output step 6*/
|
||||
#define imp_p int_vec24 /*output step 6*/
|
||||
#define warp_p bvalue1 /*warp factor */
|
||||
#define voxbnd_p ibvalue2 /*phase spectra reconstruction noise factor V*/ /* fixed point */
|
||||
#define voxbnd2_p ibvalue3 /*phase spectra reconstruction noise factor UV */ /* fixed point */
|
||||
#define E_p bvalue4 /*energy after Envelope spectrum calculation */
|
||||
#define F0_p bvalue5 /*pitch*/
|
||||
#define sMod_p bvalue6 /*speaker modification factor*/
|
||||
#define voicing bvalue7 /*voicing*/
|
||||
#define Fuv_p bvalue8 /*unrectified pitch (for unvoiced too)*/
|
||||
#define m1_p ivalue1 /*ceporder(melorder=ceporder-1) */
|
||||
#define m2_p ivalue2 /*fftorder*/
|
||||
#define windowLen_p ivalue2 /*same as fftorder*/
|
||||
#define hfftsize_p ivalue3 /*fftorder/2*/
|
||||
#define framesz_p ivalue4 /*displacement*/
|
||||
#define voiced_p ivalue5 /*voicing state*/
|
||||
#define nRes_p ivalue6 /*generic result*/
|
||||
#define i_p ivalue7 /*generic counter*/
|
||||
#define j_p ivalue8 /*generic counter*/
|
||||
#define hop_p ivalue9 /*hop */
|
||||
#define nextPeak_p ivalue10 /*nextPeak*/
|
||||
#define phId_p ivalue14 /*phonetic id*/
|
||||
#define prevVoiced_p ivalue16 /*previous voicing state (for frame 1)*/
|
||||
#define nV ivalue17
|
||||
#define nU ivalue18
|
||||
#define VoicTrans ivalue19 /* */
|
||||
#define Fs_p lvalue1 /*Sampling frequency*/
|
||||
#define VCutoff_p lvalue2 /*voicing cut off frequency in Hz*/
|
||||
#define UVCutoff_p lvalue3 /*unvoicing cut off frequency in Hz*/
|
||||
/* Reusable area */
|
||||
#define wcep_pI int_vec28 /*input step1*/
|
||||
#define d_p int_vec38 /*output mel_2_lin_init : table lookup vector D*/
|
||||
#define A_p idx_vect2 /*output mel_2_lin_init : table lookup vector A*/
|
||||
#define ang_p int_vec39 /*output step4*/
|
||||
#define EnV int_vec30
|
||||
#define EnU int_vec31
|
||||
#define randCosTbl int_vec34
|
||||
#define randSinTbl int_vec35
|
||||
#define outCosTbl int_vec36
|
||||
#define outSinTbl int_vec37
|
||||
#define cos_table int_vec40
|
||||
#define norm_window_p int_vec22 /*window function (hanning) */
|
||||
#define norm_window2_p int_vec27 /*window function (hanning) */
|
||||
#define F2r_p int_vec32 /*output step 7*/
|
||||
#define F2i_p int_vec33 /*output step 7*/
|
||||
#define LocV idx_vect8 /*excitation position voiced pulses*/
|
||||
#define LocU idx_vect9 /*excitation position unvoiced pulses*/
|
||||
|
||||
#define CepBuff int_vec41 /*Buffer for incoming cepstral vector pointers*/
|
||||
#define PhsBuff int_vec42 /*Buffer for incoming phase vector pointers*/
|
||||
#define F0Buff idx_vect10 /*Buffer for incoming F0 values*/
|
||||
#define PhIdBuff idx_vect11 /*Buffer for incoming PhId values*/
|
||||
#define VoicingBuff idx_vect12 /*Buffer for incoming voicing values*/
|
||||
#define FuVBuff idx_vect13 /*Buffer for incoming FuV values*/
|
||||
#define VoxBndBuff idx_vect14 /*Buffer for incoming VoxBnd values*/
|
||||
|
||||
#define n_available ivalue20 /*variable for indexing the incoming buffers*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+1694
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picospho.h
|
||||
*
|
||||
* sentence phonemic/phonetic FSTs PU
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
/** @addtogroup picospho
|
||||
itemtype, iteminfo1, iteminfo2, content -> TYPE(INFO1,INFO2)content
|
||||
in the following
|
||||
|
||||
items input
|
||||
===========
|
||||
|
||||
processed:
|
||||
|
||||
- WORDPHON(POS,WACC)phon
|
||||
|
||||
- BOUND(BOUNDstrength,BOUNDtype)
|
||||
|
||||
|
||||
unprocessed:
|
||||
- all other item types are forwared through the PU without modification
|
||||
|
||||
|
||||
|
||||
- POS
|
||||
a the single, unambiguous POS
|
||||
|
||||
cf. picodata.h for
|
||||
- WACC (sentence-level accent (aka prominence))
|
||||
PICODATA_ACC0
|
||||
PICODATA_ACC1
|
||||
PICODATA_ACC2 (<- maybe mapped to ACC1, ie. no ACC2 in output)
|
||||
PICODATA_ACC3
|
||||
|
||||
|
||||
- BOUNDstrength
|
||||
PICODATA_ITEMINFO1_BOUND_SBEG (sentence start)
|
||||
PICODATA_ITEMINFO1_BOUND_SEND (at sentence end)
|
||||
PICODATA_ITEMINFO1_BOUND_TERM (replaces a flush)
|
||||
PICODATA_ITEMINFO1_BOUND_PHR0 (no break)
|
||||
PICODATA_ITEMINFO1_BOUND_PHR1 (primary boundary)
|
||||
PICODATA_ITEMINFO1_BOUND_PHR2 (short break)
|
||||
PICODATA_ITEMINFO1_BOUND_PHR3 (secondary phrase boundary, no break)
|
||||
|
||||
- BOUNDtype (actually phrase type of the following phrase)
|
||||
PICODATA_ITEMINFO2_BOUNDTYPE_P (non-terminal phrase)
|
||||
PICODATA_ITEMINFO2_BOUNDTYPE_T (terminal phrase)
|
||||
PICODATA_ITEMINFO2_BOUNDTYPE_Q (question terminal phrase)
|
||||
PICODATA_ITEMINFO2_BOUNDTYPE_E (exclamation terminal phrase)
|
||||
|
||||
|
||||
output sequence (without CMDs):
|
||||
|
||||
<output> = { BOUND(BOUND_SBEG,PHRASEtype) <sentence> BOUND(BOUND_SEND,..)} BOUND(BOUND_TERM,..)
|
||||
|
||||
<sentence> = <phrase> { BOUND(BOUND_PHR1|2|3,PHRASEtype) <phrase> }
|
||||
|
||||
<phrase> = WORDPHON(POS,ACC)phon { WORDPHON(POS,ACC)phon }
|
||||
|
||||
|
||||
|
||||
mapping ACC & word-level stress to syllable accent value
|
||||
|
||||
ACC0 prim -> 0
|
||||
ACC1 prim -> 1
|
||||
ACC2 prim -> 2
|
||||
ACC3 prim -> 3
|
||||
|
||||
ACC0 sec -> 0
|
||||
ACC1 sec -> 4
|
||||
ACC2 sec -> 4
|
||||
ACC3 sec -> 4
|
||||
|
||||
Mapping of values to FST symbol id (has to identical to the symbol table used when compiling the FST)
|
||||
|
||||
Value FST symbol id
|
||||
phoneme_id -> phoneme_id + 256 * PICOKFST_PLANE_PHONEMES
|
||||
POS_id -> POS_id + 256 * PICOKFST_PLANE_POS
|
||||
phrasetype_id -> phrasetype_id + 256 * PICOKFST_PLANE_PHRASETYPES
|
||||
accentlevel_id -> accentlevel_id + 256 * PICOKFST_PLANE_ACCENTS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
minimal input size (before processing starts)
|
||||
==================
|
||||
|
||||
processing (ie. sequencially applying spho transducers to phoneme sequence composed of
|
||||
- phonemes inside WORDPHON items and
|
||||
- pseudo-phonemes derived from boundaries and POS) is possible with
|
||||
|
||||
- one phrase, consisting of a sequence of maximal 30 non-PUNC items
|
||||
terminated by a PUNC item. A PUNC is artificially enforced if
|
||||
needed to start processing.
|
||||
|
||||
- as long as the internal buffer is empty, non-processed item types
|
||||
can be processed immediately
|
||||
|
||||
|
||||
|
||||
items output
|
||||
============
|
||||
- BOUND(BOUNDstrength,BOUNDtype)
|
||||
|
||||
bound strength may be changed by the fsts
|
||||
|
||||
in addition, BOUNDs of BOUNDstrength = PHR0 are inserted to mark word boundaries
|
||||
|
||||
- SYLLPHON(POS,ACC)phon
|
||||
where POS is only set for the first syllable of a word, otherwise NA
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
other limitations
|
||||
=================
|
||||
|
||||
|
||||
*/
|
||||
#ifndef PICOSPHO_H_
|
||||
#define PICOSPHO_H_
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picodata.h"
|
||||
#include "picorsrc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
picodata_ProcessingUnit picospho_newSentPhoUnit(
|
||||
picoos_MemoryManager mm,
|
||||
picoos_Common common,
|
||||
picodata_CharBuffer cbIn,
|
||||
picodata_CharBuffer cbOut,
|
||||
picorsrc_Voice voice);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*PICOSPHO_H_*/
|
||||
+1577
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picotok.h
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup picotok
|
||||
itemtype, iteminfo1, iteminfo2, content -> TYPE(INFO1,INFO2)content
|
||||
in the following
|
||||
|
||||
input
|
||||
=====
|
||||
|
||||
- UTF8 text
|
||||
|
||||
limitations: currently only german umlauts in addition to ASCII
|
||||
|
||||
|
||||
minimal input size (before processing starts)
|
||||
==================
|
||||
|
||||
processing (ie. tokenization) starts when
|
||||
- 'PICO_EOF' char received (which happens whenever the cbIn buffer is empty)
|
||||
- tok-internal buffer is full
|
||||
|
||||
|
||||
items output
|
||||
============
|
||||
|
||||
processing the character stream can result in one of the
|
||||
following items:
|
||||
-> WORDGRAPH(NA,NA)graph <- mapped to lower case; incl. 1-2 digit nrs (0-99)
|
||||
-> OTHER(NA,NA)string <- skip or spell
|
||||
-> PUNC(PUNCtype,PUNCsubtype)
|
||||
-> CMD(CMDtype,CMDsubtype)args
|
||||
|
||||
with
|
||||
- PUNCtype %d
|
||||
PICODATA_ITEMINFO1_PUNC_SENTEND
|
||||
PICODATA_ITEMINFO1_PUNC_PHRASEEND
|
||||
- PUNCsubtype %d
|
||||
PICODATA_ITEMINFO2_PUNC_SENT_T
|
||||
PICODATA_ITEMINFO2_PUNC_SENT_Q
|
||||
PICODATA_ITEMINFO2_PUNC_SENT_E
|
||||
PICODATA_ITEMINFO2_PUNC_PHRASE
|
||||
(used later: PICODATA_ITEMINFO2_PUNC_PHRASE_FORCED)
|
||||
- CMDtype %d
|
||||
PICODATA_ITEMINFO1_CMD_FLUSH (no args)
|
||||
? PICODATA_ITEMINFO1_CMD_PLAY ? (not yet)
|
||||
- CMDsubtype %d
|
||||
PICODATA_ITEMINFO2_NA
|
||||
? PICODATA_ITEMINFO2_CMD_PLAY_G2P ? (not yet)
|
||||
- graph, len>0, utf8 graphemes, %s
|
||||
- string, len>0, can be any string with printable ascii characters, %s
|
||||
|
||||
|
||||
other limitations
|
||||
=================
|
||||
|
||||
- item size: header plus len=256 (valid for Pico in general)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PICOTOK_H_
|
||||
#define PICOTOK_H_
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picodata.h"
|
||||
#include "picorsrc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
picodata_ProcessingUnit picotok_newTokenizeUnit(
|
||||
picoos_MemoryManager mm,
|
||||
picoos_Common common,
|
||||
picodata_CharBuffer cbIn,
|
||||
picodata_CharBuffer cbOut,
|
||||
picorsrc_Voice voice);
|
||||
|
||||
#define PICOTOK_OUTBUF_SIZE 256
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*PICOTOK_H_*/
|
||||
@@ -0,0 +1,745 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picotrns.c
|
||||
*
|
||||
* fst processing
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picodbg.h"
|
||||
/* #include "picodata.h" */
|
||||
/* #include "picoknow.h" */
|
||||
#include "picoktab.h"
|
||||
#include "picokfst.h"
|
||||
#include "picotrns.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
picoos_uint8 picotrns_unplane(picoos_int16 symIn, picoos_uint8 * plane) {
|
||||
if (symIn < 0) {
|
||||
(*plane) = 0;
|
||||
return (picoos_uint8) symIn;
|
||||
} else {
|
||||
(*plane) = symIn >> 8;
|
||||
return (picoos_uint8) (symIn & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(PICO_DEBUG)
|
||||
|
||||
void PICOTRNS_PRINTSYM1(picoknow_KnowledgeBase kbdbg, picoos_int16 insym, picoos_uint8 phonemic)
|
||||
{
|
||||
#include "picokdbg.h"
|
||||
picoos_int16 sym;
|
||||
picoos_uint8 plane;
|
||||
picokdbg_Dbg dbg = (NULL == kbdbg) ? NULL : picokdbg_getDbg(kbdbg);
|
||||
sym = picotrns_unplane(insym, &plane);
|
||||
switch (plane) {
|
||||
case PICOKFST_PLANE_PHONEMES: /* phones */
|
||||
if ((NULL == dbg) || !phonemic) {
|
||||
PICODBG_INFO_MSG((" %c", sym));
|
||||
} else {
|
||||
PICODBG_INFO_MSG((" %s", picokdbg_getPhoneSym(dbg, (picoos_uint8) sym)));
|
||||
}
|
||||
break;
|
||||
case PICOKFST_PLANE_ACCENTS: /* accents */
|
||||
PICODBG_INFO_MSG((" {A%c}", sym));
|
||||
break;
|
||||
case PICOKFST_PLANE_XSAMPA: /* xsampa symbols */
|
||||
PICODBG_INFO_MSG((" {XS:(%i)}", sym));
|
||||
break;
|
||||
case PICOKFST_PLANE_POS: /* part of speech */
|
||||
PICODBG_INFO_MSG((" {P:%d}", sym));
|
||||
break;
|
||||
case PICOKFST_PLANE_PB_STRENGTHS: /* phrases */
|
||||
if (sym == 48) {
|
||||
PICODBG_INFO_MSG((" {WB}", sym));
|
||||
} else if (sym == 115) {
|
||||
PICODBG_INFO_MSG((" {P0}", sym));
|
||||
} else {
|
||||
PICODBG_INFO_MSG((" {P%c}", sym));
|
||||
}
|
||||
break;
|
||||
case PICOKFST_PLANE_INTERN: /* intern */
|
||||
PICODBG_INFO_MSG((" [%c]", sym));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PICOTRNS_PRINTSYM(picoknow_KnowledgeBase kbdbg, picoos_int16 insym)
|
||||
{
|
||||
PICOTRNS_PRINTSYM1(kbdbg,insym,1);
|
||||
}
|
||||
|
||||
void PICOTRNS_PRINTSYMSEQ1(picoknow_KnowledgeBase kbdbg, const picotrns_possym_t seq[], const picoos_uint16 seqLen,
|
||||
picoos_uint8 phonemic) {
|
||||
picoos_uint16 i;
|
||||
for (i=0; i<seqLen; i++) {
|
||||
PICOTRNS_PRINTSYM1(kbdbg, seq[i].sym, phonemic);
|
||||
}
|
||||
}
|
||||
|
||||
void PICOTRNS_PRINTSYMSEQ(picoknow_KnowledgeBase kbdbg, const picotrns_possym_t seq[], const picoos_uint16 seqLen) {
|
||||
PICOTRNS_PRINTSYMSEQ1(kbdbg,seq, seqLen, 1);
|
||||
}
|
||||
|
||||
void picotrns_printSolution(const picotrns_possym_t outSeq[], const picoos_uint16 outSeqLen)
|
||||
{
|
||||
PICODBG_INFO_CTX();
|
||||
PICODBG_INFO_MSG(("solution: "));
|
||||
PICOTRNS_PRINTSYMSEQ(NULL, outSeq, outSeqLen);
|
||||
PICODBG_INFO_MSG(("\n"));
|
||||
}
|
||||
|
||||
void picotrns_printSolutionAscii(const picotrns_possym_t outSeq[], const picoos_uint16 outSeqLen)
|
||||
{
|
||||
PICODBG_INFO_CTX();
|
||||
PICODBG_INFO_MSG(("solution: "));
|
||||
PICOTRNS_PRINTSYMSEQ1(NULL, outSeq, outSeqLen,0);
|
||||
PICODBG_INFO_MSG(("\n"));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/* * +CT+ ***/
|
||||
struct picotrns_transductionState {
|
||||
picoos_uint16 phase; /* transduction phase:
|
||||
0 = before start
|
||||
1 = before regular recursion step
|
||||
2 = before finish
|
||||
3 = after finish */
|
||||
picoos_uint32 nrSol; /* nr of solutions so far */
|
||||
picoos_int16 recPos; /* recursion position; must be signed! */
|
||||
};
|
||||
|
||||
typedef struct picotrns_altDesc {
|
||||
picokfst_state_t startFSTState; /**< starting FST state in current recursion position */
|
||||
picoos_int32 inPos; /**< corresponding position in input string */
|
||||
picokfst_state_t altState; /**< state of alternatives search;
|
||||
- 0 = before pair search
|
||||
- 1 = search state is a valid pair search state
|
||||
- 2 = before inEps search
|
||||
- 3 = search state is a valid inEps trans search state
|
||||
- 4 = no more alternatives */
|
||||
picoos_int32 searchState; /**< pair search state or inEps trans search state */
|
||||
picokfst_symid_t altOutSym; /**< current output symbol at this recursion position */
|
||||
picoos_int32 altOutRefPos; /**< output reference position at this recursion position */
|
||||
} picotrns_altDesc_t;
|
||||
|
||||
|
||||
picotrns_AltDesc picotrns_allocate_alt_desc_buf(picoos_MemoryManager mm, picoos_uint32 maxByteSize, picoos_uint16 * numAltDescs)
|
||||
{
|
||||
picotrns_AltDesc buf;
|
||||
(*numAltDescs) = (picoos_uint32) (maxByteSize / sizeof(picotrns_altDesc_t));
|
||||
buf = (picotrns_AltDesc) picoos_allocate(mm, (*numAltDescs) * sizeof(picotrns_altDesc_t));
|
||||
if (NULL == buf) {
|
||||
(*numAltDescs) = 0;
|
||||
return NULL;
|
||||
} else {
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
void picotrns_deallocate_alt_desc_buf(picoos_MemoryManager mm, picotrns_AltDesc * altDescBuf)
|
||||
{
|
||||
picoos_deallocate(mm, (void *) altDescBuf);
|
||||
}
|
||||
|
||||
/* copy elements from inSeq to outSeq, ignoring elements with epsilon symbol */
|
||||
pico_status_t picotrns_eliminate_epsilons(const picotrns_possym_t inSeq[], picoos_uint16 inSeqLen,
|
||||
picotrns_possym_t outSeq[], picoos_uint16 * outSeqLen, picoos_uint16 maxOutSeqLen)
|
||||
{
|
||||
picoos_uint16 i, j = 0;
|
||||
|
||||
for (i=0; i < inSeqLen; i++) {
|
||||
/* it is assumed that PICOKFST_SYMID_EPS is a hardwired value and not shifted */
|
||||
if (PICOKFST_SYMID_EPS != inSeq[i].sym) {
|
||||
if (j < maxOutSeqLen) {
|
||||
outSeq[j].pos = inSeq[i].pos;
|
||||
outSeq[j].sym = inSeq[i].sym;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
*outSeqLen = j;
|
||||
}
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
static void insertSym(picotrns_possym_t inSeq[], picoos_uint16 pos, picoos_int16 sym) {
|
||||
inSeq[pos].sym = sym;
|
||||
inSeq[pos].pos = PICOTRNS_POS_INSERT;
|
||||
}
|
||||
|
||||
/* copy elements from inSeq to outSeq, inserting syllable separators in some trivial way.
|
||||
* inSeq is assumed to be at most PICOTRNS_MAX_NUM_POSSYM, outSeq at least of size PICOTRNS_MAX_NUM_POSSYM */
|
||||
pico_status_t picotrns_trivial_syllabify(picoktab_Phones phones,
|
||||
const picotrns_possym_t inSeq[], const picoos_uint16 inSeqLen,
|
||||
picotrns_possym_t outSeq[], picoos_uint16 * outSeqLen, picoos_uint16 maxOutSeqLen)
|
||||
{
|
||||
picoos_uint16 i = 0, j = 0, out = 0, numInserted = 0;
|
||||
picoos_uint8 vowelFound = FALSE;
|
||||
picoos_uint16 accentpos = 0;
|
||||
picoos_int16 accent = 0;
|
||||
|
||||
PICODBG_TRACE(("start"));
|
||||
|
||||
|
||||
while (i < inSeqLen) {
|
||||
/* make sure that at least one more sylSep can be inserted */
|
||||
if (inSeqLen+numInserted+1 >= maxOutSeqLen) {
|
||||
return PICO_EXC_BUF_OVERFLOW;
|
||||
}
|
||||
/* let j skip consonant cluster */
|
||||
accent = 0;
|
||||
accentpos = 0;
|
||||
while ((j < inSeqLen) && !picoktab_isSyllCarrier(phones,(picoos_uint8)inSeq[j].sym)) {
|
||||
if ((inSeq[j].sym == picoktab_getPrimstressID(phones))
|
||||
|| (inSeq[j].sym == picoktab_getPrimstressID(phones))) {
|
||||
PICODBG_TRACE(("j skipping stress symbol inSeq[%i].sym = %c", j, inSeq[j].sym));
|
||||
accent = inSeq[j].sym;
|
||||
accentpos = j;
|
||||
} else {
|
||||
PICODBG_TRACE(("j skipping consonant inSeq[%i].sym = %c", j, inSeq[j].sym));
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (j < inSeqLen) { /* j is at the start of a new vowel */
|
||||
/* copy consonant cluster (moving i) to output, insert syll separator if between vowels */
|
||||
while (i < j-1) {
|
||||
if ((accent > 0) && (i == accentpos)) {
|
||||
PICODBG_TRACE(("skipping inSeq[%i].sym = %c (stress)", i, inSeq[i].sym));
|
||||
i++;
|
||||
} else {
|
||||
PICODBG_TRACE(("copying inSeq[%i].sym = %c (consonant) into output buffer", i, inSeq[i].sym));
|
||||
outSeq[out++] = inSeq[i++];
|
||||
}
|
||||
}
|
||||
if (vowelFound) { /* we're between vowels */
|
||||
PICODBG_TRACE(("inserting syllable separator into output buffer"));
|
||||
insertSym(outSeq,out++,picoktab_getSyllboundID(phones));
|
||||
if (accent > 0) {
|
||||
insertSym(outSeq,out++,accent);
|
||||
}
|
||||
numInserted++;
|
||||
}
|
||||
if ((accent > 0) && (i == accentpos)) {
|
||||
PICODBG_TRACE(("skipping inSeq[%i].sym = %c (stress)", i, inSeq[i].sym));
|
||||
i++;
|
||||
} else {
|
||||
PICODBG_TRACE(("copying inSeq[%i].sym = %c (consonant) into output buffer", i, inSeq[i].sym));
|
||||
outSeq[out++] = inSeq[i++];
|
||||
}
|
||||
vowelFound = TRUE;
|
||||
/* now copy vowel cluster */
|
||||
while ((i < inSeqLen) && picoktab_isSyllCarrier(phones,(picoos_uint8)inSeq[i].sym)) {
|
||||
PICODBG_TRACE(("copying inSeq[%i].sym = %c (vowel) into output buffer", i, inSeq[i].sym));
|
||||
outSeq[out++] = inSeq[i++];
|
||||
}
|
||||
j = i;
|
||||
} else { /* j is at end of word or end of input */
|
||||
while (i < j) {
|
||||
PICODBG_TRACE(("copying inSeq[%i].sym = %c (consonant or stress) into output buffer", i, inSeq[i].sym));
|
||||
outSeq[out++] = inSeq[i++];
|
||||
}
|
||||
}
|
||||
*outSeqLen = out;
|
||||
}
|
||||
PICODBG_ASSERT((out == inSeqLen + numInserted));
|
||||
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
/* ******** +CT+: full transduction procedure **********/
|
||||
|
||||
|
||||
/* Gets next acceptable alternative for output symbol '*outSym' at current recursion position
|
||||
starting from previous alternative in 'altDesc'; possibly uses input symbol
|
||||
given by 'inSeq'/'inSeq'; returns whether alterative was found in '*found';
|
||||
if '*found', the other output values ('*outRefPos', '*endFSTstate', '*nextInPos'*)
|
||||
return the characteristics for next recursion step;
|
||||
if '*found' is false, the output values are undefined. */
|
||||
|
||||
static void GetNextAlternative (picokfst_FST fst, picotrns_AltDesc altDesc,
|
||||
const picotrns_possym_t inSeq[], picoos_uint16 inSeqLen,
|
||||
picokfst_symid_t * outSym, picoos_int32 * outRefPos,
|
||||
picokfst_state_t * endFSTState, picoos_int32 * nextInPos, picoos_bool * found)
|
||||
{
|
||||
|
||||
picoos_bool inSymFound;
|
||||
picoos_bool pairFound;
|
||||
picokfst_class_t pairClass;
|
||||
picoos_bool inEpsTransFound;
|
||||
picokfst_symid_t inSym;
|
||||
|
||||
(*found) = 0;
|
||||
do {
|
||||
switch (altDesc->altState) {
|
||||
case 0: /* before pair search */
|
||||
if (altDesc->inPos < inSeqLen) {
|
||||
inSym = inSeq[altDesc->inPos].sym;
|
||||
if (inSym == PICOKFST_SYMID_EPS) {
|
||||
/* very special case: input epsilon simply produces eps in output
|
||||
without fst state change */
|
||||
(*found) = 1;
|
||||
(*outSym) = PICOKFST_SYMID_EPS;
|
||||
(*outRefPos) = inSeq[altDesc->inPos].pos;
|
||||
(*endFSTState) = altDesc->startFSTState;
|
||||
(*nextInPos) = altDesc->inPos + 1;
|
||||
altDesc->altState = 2;
|
||||
} else {
|
||||
/* start search for alternatives using input symbol */
|
||||
picokfst_kfstStartPairSearch(fst,inSeq[altDesc->inPos].sym,& inSymFound,& altDesc->searchState);
|
||||
if (!inSymFound) {
|
||||
altDesc->altState = 2;
|
||||
PICODBG_INFO_CTX();
|
||||
PICODBG_INFO_MSG((" didnt find symbol "));
|
||||
PICOTRNS_PRINTSYM(NULL, inSeq[altDesc->inPos].sym);
|
||||
PICODBG_INFO_MSG(("\n"));
|
||||
|
||||
} else {
|
||||
altDesc->altState = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
altDesc->altState = 2;
|
||||
}
|
||||
break;
|
||||
case 1: /* within pair search */
|
||||
picokfst_kfstGetNextPair(fst,& altDesc->searchState,& pairFound,& (*outSym),& pairClass);
|
||||
if (pairFound) {
|
||||
picokfst_kfstGetTrans(fst,altDesc->startFSTState,pairClass,& (*endFSTState));
|
||||
if ((*endFSTState) > 0) {
|
||||
(*found) = 1;
|
||||
(*outRefPos) = inSeq[altDesc->inPos].pos;
|
||||
(*nextInPos) = altDesc->inPos + 1;
|
||||
}
|
||||
} else {
|
||||
/* no more pair found */
|
||||
altDesc->altState = 2;
|
||||
}
|
||||
break;
|
||||
case 2: /* before inEps trans search */
|
||||
picokfst_kfstStartInEpsTransSearch(fst,altDesc->startFSTState,& inEpsTransFound,& altDesc->searchState);
|
||||
if (inEpsTransFound) {
|
||||
altDesc->altState = 3;
|
||||
} else {
|
||||
altDesc->altState = 4;
|
||||
}
|
||||
break;
|
||||
case 3: /* within inEps trans search */
|
||||
picokfst_kfstGetNextInEpsTrans(fst,& altDesc->searchState,& inEpsTransFound,& (*outSym),& (*endFSTState));
|
||||
if (inEpsTransFound) {
|
||||
(*found) = 1;
|
||||
(*outRefPos) = PICOTRNS_POS_INSERT;
|
||||
(*nextInPos) = altDesc->inPos;
|
||||
} else {
|
||||
altDesc->altState = 4;
|
||||
}
|
||||
break;
|
||||
case 4: /* no more alternatives */
|
||||
break;
|
||||
}
|
||||
} while (! ((*found) || (altDesc->altState == 4)) ); /* i.e., until (*found) || (altState == 4) */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Transfers current alternatives path stored in 'altDesc' with current path length 'pathLen'
|
||||
into 'outSeq'/'outSeqLen'. The number of solutions is incremented. */
|
||||
|
||||
static void NoteSolution (picoos_uint32 * nrSol, picotrns_printSolutionFct printSolution,
|
||||
picotrns_altDesc_t altDesc[], picoos_uint16 pathLen,
|
||||
picotrns_possym_t outSeq[], picoos_uint16 * outSeqLen, picoos_uint16 maxOutSeqLen)
|
||||
{
|
||||
register picotrns_AltDesc ap;
|
||||
picoos_uint32 i;
|
||||
|
||||
(*nrSol)++;
|
||||
(*outSeqLen) = 0;
|
||||
for (i = 0; i < pathLen; i++) {
|
||||
if (i < maxOutSeqLen) {
|
||||
ap = &altDesc[i];
|
||||
outSeq[i].sym = ap->altOutSym;
|
||||
outSeq[i].pos = ap->altOutRefPos;
|
||||
(*outSeqLen)++;
|
||||
}
|
||||
}
|
||||
if (pathLen > maxOutSeqLen) {
|
||||
PICODBG_WARN(("**** output symbol array too small to hold full solution\n"));
|
||||
}
|
||||
if (printSolution != NULL) {
|
||||
printSolution(outSeq,(*outSeqLen));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *
|
||||
general scheme to get all solutions ("position" refers to abstract backtracking recursion depth,
|
||||
which in the current solution is equal to the output symbol position):
|
||||
|
||||
"set position to first position";
|
||||
"initialize alternatives in first position";
|
||||
REPEAT
|
||||
IF "current state in current position is a solution" THEN
|
||||
"note solution";
|
||||
END;
|
||||
"get first or next acceptable alternative in current position";
|
||||
IF "acceptable alternative found" THEN
|
||||
"note alternative";
|
||||
"go to next position";
|
||||
"initialize alternatives in that position";
|
||||
ELSE
|
||||
"step back to previous position";
|
||||
END;
|
||||
UNTIL "current position is before first position"
|
||||
***/
|
||||
|
||||
|
||||
/* Initializes transduction state for further use in repeated application
|
||||
of 'TransductionStep'. */
|
||||
|
||||
static void StartTransduction (struct picotrns_transductionState * transductionState)
|
||||
{
|
||||
(*transductionState).phase = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Performs one step in the transduction of 'inSeqLen' input symbols with corresponding
|
||||
reference positions in 'inSeq'. '*transductionState' must have been
|
||||
initialized by 'StartTransduction'. Repeat calls to this procedure until '*finished' returns true.
|
||||
The output is returned in 'outSeqLen' symbols and reference positions in 'outSeq'.
|
||||
The output reference positions refer to the corresponding input reference positions.
|
||||
Inserted output symbols receive the reference position -1. If several solutions are possible,
|
||||
only the last found solution is returned.
|
||||
'altDesc' is a temporary workspace which should be at least one cell longer than 'outSeq'.
|
||||
'firstSolOnly' determines whether only the first solution should be found or if
|
||||
the search should go on to find all solutions (mainly for testing purposes).
|
||||
|
||||
NOTE: current version written for use in single repetitive steps;
|
||||
could be simplified if full transduction can be done as an atomic operation */
|
||||
|
||||
static void TransductionStep (picokfst_FST fst, struct picotrns_transductionState * transductionState,
|
||||
picotrns_altDesc_t altDesc[], picoos_uint16 maxAltDescLen,
|
||||
picoos_bool firstSolOnly, picotrns_printSolutionFct printSolution,
|
||||
const picotrns_possym_t inSeq[], picoos_uint16 inSeqLen,
|
||||
picotrns_possym_t outSeq[], picoos_uint16 * outSeqLen, picoos_uint16 maxOutSeqLen,
|
||||
picoos_bool * finished)
|
||||
{
|
||||
register picotrns_AltDesc ap;
|
||||
picoos_int32 i;
|
||||
picokfst_state_t endFSTState;
|
||||
picoos_int32 nextInPos;
|
||||
picoos_bool found;
|
||||
picokfst_symid_t outSym;
|
||||
picoos_int32 outRefPos;
|
||||
picoos_int32 tmpRecPos;
|
||||
|
||||
(*finished) = 0;
|
||||
tmpRecPos = (*transductionState).recPos;
|
||||
switch ((*transductionState).phase) {
|
||||
case 0: /* before initialization */
|
||||
(*transductionState).nrSol = 0;
|
||||
|
||||
/* check for initial solution (empty strings are always accepted) */
|
||||
if (inSeqLen == 0) {
|
||||
NoteSolution(& (*transductionState).nrSol,printSolution,altDesc,0,outSeq,outSeqLen,maxOutSeqLen);
|
||||
}
|
||||
|
||||
/* initialize first recursion position */
|
||||
tmpRecPos = 0;
|
||||
ap = & altDesc[0];
|
||||
ap->startFSTState = 1;
|
||||
ap->inPos = 0;
|
||||
ap->altState = 0;
|
||||
(*transductionState).phase = 1;
|
||||
break;
|
||||
|
||||
case 1: /* before regular recursion step */
|
||||
if ((tmpRecPos < 0) || (firstSolOnly && ((*transductionState).nrSol > 0))) {
|
||||
/* end reached */
|
||||
(*transductionState).phase = 2;
|
||||
} else {
|
||||
/* not finished; do regular step */
|
||||
|
||||
/* get first or next acceptable alternative in current position */
|
||||
GetNextAlternative(fst,& altDesc[tmpRecPos],inSeq,inSeqLen,& outSym,& outRefPos,& endFSTState,& nextInPos,& found);
|
||||
if (found) {
|
||||
/* note alternative in current position */
|
||||
ap = & altDesc[tmpRecPos];
|
||||
ap->altOutSym = outSym;
|
||||
ap->altOutRefPos = outRefPos;
|
||||
|
||||
/* check for solution after found alternative */
|
||||
if ((nextInPos == inSeqLen) && picokfst_kfstIsAcceptingState(fst,endFSTState)) {
|
||||
NoteSolution(& (*transductionState).nrSol,printSolution,altDesc,tmpRecPos+1,
|
||||
outSeq,outSeqLen,maxOutSeqLen);
|
||||
}
|
||||
|
||||
/* go to next position if possible, start search for follower alternative symbols */
|
||||
if (tmpRecPos < maxAltDescLen-1) {
|
||||
/* got to next position */
|
||||
tmpRecPos = tmpRecPos + 1;
|
||||
|
||||
/* initialize alternatives in new position */
|
||||
ap = & altDesc[tmpRecPos];
|
||||
ap->startFSTState = endFSTState;
|
||||
ap->inPos = nextInPos;
|
||||
ap->altState = 0;
|
||||
|
||||
} else {
|
||||
/* do not go on due to limited path but still treat alternatives in current position */
|
||||
PICODBG_WARN(("--- transduction path too long; may fail to find solution\n"));
|
||||
}
|
||||
} else { /* no more acceptable alternative found in current position */
|
||||
/* backtrack to previous recursion */
|
||||
tmpRecPos = tmpRecPos - 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /* before finish */
|
||||
if ((*transductionState).nrSol == 0) {
|
||||
PICODBG_WARN(("--- no transduction solution found, using input as output\n"));
|
||||
i = 0;
|
||||
while ((i < inSeqLen) && (i < maxOutSeqLen)) {
|
||||
outSeq[i].sym = inSeq[i].sym;
|
||||
outSeq[i].pos = inSeq[i].pos;
|
||||
i++;
|
||||
}
|
||||
(*outSeqLen) = i;
|
||||
} else if ((*transductionState).nrSol > 1) {
|
||||
PICODBG_WARN(("--- more than one transducer solutions found\n"));
|
||||
}
|
||||
(*transductionState).phase = 3;
|
||||
break;
|
||||
|
||||
case 3: /* after finish */
|
||||
(*finished) = 1;
|
||||
break;
|
||||
}
|
||||
(*transductionState).recPos = tmpRecPos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* see description in header */
|
||||
pico_status_t picotrns_transduce (picokfst_FST fst, picoos_bool firstSolOnly,
|
||||
picotrns_printSolutionFct printSolution,
|
||||
const picotrns_possym_t inSeq[], picoos_uint16 inSeqLen,
|
||||
picotrns_possym_t outSeq[], picoos_uint16 * outSeqLen, picoos_uint16 maxOutSeqLen,
|
||||
picotrns_AltDesc altDescBuf, picoos_uint16 maxAltDescLen,
|
||||
picoos_uint32 *nrSteps)
|
||||
{
|
||||
struct picotrns_transductionState transductionState;
|
||||
picoos_bool finished;
|
||||
|
||||
#if defined(PICO_DEBUG)
|
||||
{
|
||||
picoos_uint16 i;
|
||||
|
||||
PICODBG_INFO_CTX();
|
||||
PICODBG_INFO_MSG(("got input: "));
|
||||
for (i=0; i<inSeqLen; i++) {
|
||||
PICODBG_INFO_MSG((" %d", inSeq[i].sym));
|
||||
}
|
||||
PICODBG_INFO_MSG((" ("));
|
||||
PICOTRNS_PRINTSYMSEQ(NULL,inSeq,inSeqLen);
|
||||
PICODBG_INFO_MSG((")\n"));
|
||||
}
|
||||
#endif
|
||||
StartTransduction(&transductionState);
|
||||
finished = 0;
|
||||
*nrSteps = 0;
|
||||
while (!finished) {
|
||||
TransductionStep(fst,&transductionState,altDescBuf,maxAltDescLen,firstSolOnly,printSolution,
|
||||
inSeq,inSeqLen,outSeq,outSeqLen,maxOutSeqLen,&finished);
|
||||
(*nrSteps)++;
|
||||
}
|
||||
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Data structure for picotrns_SimpleTransducer object.
|
||||
*/
|
||||
typedef struct picotrns_simple_transducer {
|
||||
picoos_Common common;
|
||||
picotrns_possym_t possymBufA[PICOTRNS_MAX_NUM_POSSYM+1];
|
||||
picotrns_possym_t possymBufB[PICOTRNS_MAX_NUM_POSSYM+1];
|
||||
picotrns_possym_t * possymBuf; /**< the buffer of the pos/sym pairs */
|
||||
picotrns_possym_t * possymBufTmp;
|
||||
picoos_uint16 possymReadPos, possymWritePos; /* next pos to read from phonBufIn, next pos to write to phonBufIn */
|
||||
|
||||
/* buffer for internal calculation of transducer */
|
||||
picotrns_AltDesc altDescBuf;
|
||||
/* the number of AltDesc in the buffer */
|
||||
picoos_uint16 maxAltDescLen;
|
||||
} picotrns_simple_transducer_t;
|
||||
|
||||
|
||||
pico_status_t picotrns_stInitialize(picotrns_SimpleTransducer transducer)
|
||||
{
|
||||
transducer->possymBuf = transducer->possymBufA;
|
||||
transducer->possymBufTmp = transducer->possymBufB;
|
||||
transducer->possymReadPos = 0;
|
||||
transducer->possymWritePos = 0;
|
||||
return PICO_OK;
|
||||
}
|
||||
/** creates a SimpleTranducer with a working buffer of given size
|
||||
*
|
||||
* @param mm MemoryManager handle
|
||||
* @param common Common handle
|
||||
* @param maxAltDescLen maximal size for working buffer (in bytes)
|
||||
* @return handle to new SimpleTransducer or NULL if error
|
||||
*/
|
||||
picotrns_SimpleTransducer picotrns_newSimpleTransducer(picoos_MemoryManager mm,
|
||||
picoos_Common common,
|
||||
picoos_uint16 maxAltDescLen)
|
||||
{
|
||||
picotrns_SimpleTransducer this;
|
||||
this = picoos_allocate(mm, sizeof(picotrns_simple_transducer_t));
|
||||
if (this == NULL) {
|
||||
picoos_deallocate(mm, (void *)&this);
|
||||
picoos_emRaiseException(common->em, PICO_EXC_OUT_OF_MEM, NULL, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* allocate working buffer */
|
||||
this->altDescBuf = picotrns_allocate_alt_desc_buf(mm, maxAltDescLen, &this->maxAltDescLen);
|
||||
if (this->altDescBuf == NULL) {
|
||||
picoos_deallocate(mm, (void *)&this);
|
||||
picoos_emRaiseException(common->em, PICO_EXC_OUT_OF_MEM, NULL, NULL);
|
||||
return NULL;
|
||||
}
|
||||
this->common = common;
|
||||
picotrns_stInitialize(this);
|
||||
return this;
|
||||
}
|
||||
/** disposes a SimpleTransducer
|
||||
*
|
||||
* @param this
|
||||
* @param mm
|
||||
* @return PICO_OK
|
||||
*/
|
||||
pico_status_t picotrns_disposeSimpleTransducer(picotrns_SimpleTransducer * this,
|
||||
picoos_MemoryManager mm)
|
||||
{
|
||||
if (NULL != (*this)) {
|
||||
picotrns_deallocate_alt_desc_buf(mm,&(*this)->altDescBuf);
|
||||
picoos_deallocate(mm, (void *) this);
|
||||
(*this) = NULL;
|
||||
}
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
/** transduces the contents previously inserted via @ref picotrns_newSimpleTransducer and @ref
|
||||
* picotrns_disposeSimpleTransducer.
|
||||
*
|
||||
* @param this
|
||||
* @param fst
|
||||
* @return
|
||||
*/
|
||||
pico_status_t picotrns_stTransduce(picotrns_SimpleTransducer this, picokfst_FST fst)
|
||||
{
|
||||
picoos_uint16 outSeqLen;
|
||||
picoos_uint32 nrSteps;
|
||||
pico_status_t status;
|
||||
|
||||
status = picotrns_transduce(fst,TRUE,NULL,
|
||||
this->possymBuf, this->possymWritePos,
|
||||
this->possymBufTmp,&outSeqLen, PICOTRNS_MAX_NUM_POSSYM,
|
||||
this->altDescBuf,this->maxAltDescLen,&nrSteps);
|
||||
if (PICO_OK != status) {
|
||||
return status;
|
||||
}
|
||||
return picotrns_eliminate_epsilons(this->possymBufTmp,outSeqLen,this->possymBuf,&this->possymWritePos,PICOTRNS_MAX_NUM_POSSYM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add chars from NULLC-terminated string \c inStr, shifted to plane \c plane, to internal input buffer of
|
||||
* \c transducer.
|
||||
*
|
||||
* @param this is an initialized picotrns_SimpleTransducer
|
||||
* @param inStr NULLC-terminated byte sequence
|
||||
* @param plane
|
||||
* @return PICO_OK, if all bytes fit into buffer, or PICO_EXC_BUF_OVERFLOW otherwise
|
||||
*/
|
||||
pico_status_t picotrns_stAddWithPlane(picotrns_SimpleTransducer this, picoos_char * inStr, picoos_uint8 plane)
|
||||
{
|
||||
while ((*inStr) && (this->possymWritePos < PICOTRNS_MAX_NUM_POSSYM)) {
|
||||
this->possymBuf[this->possymWritePos].pos = PICOTRNS_POS_INSERT;
|
||||
this->possymBuf[this->possymWritePos].sym = (plane << 8) + (*inStr);
|
||||
PICODBG_DEBUG(("inserting pos/sym = %i/'%c' at pos %i",
|
||||
this->possymBuf[this->possymWritePos].pos,
|
||||
this->possymBuf[this->possymWritePos].sym,
|
||||
this->possymWritePos));
|
||||
this->possymWritePos++;
|
||||
inStr++;
|
||||
}
|
||||
if (!(*inStr)) {
|
||||
return PICO_OK;
|
||||
} else {
|
||||
return PICO_EXC_BUF_OVERFLOW;
|
||||
}
|
||||
}
|
||||
|
||||
pico_status_t picotrns_stGetSymSequence(
|
||||
picotrns_SimpleTransducer this,
|
||||
picoos_uint8 * outputSymIds,
|
||||
picoos_uint32 maxOutputSymIds)
|
||||
{
|
||||
picoos_uint8 plane;
|
||||
picoos_uint32 outputCount = 0;
|
||||
while ((this->possymReadPos < this->possymWritePos) && (outputCount < maxOutputSymIds)) {
|
||||
*outputSymIds++ = picotrns_unplane(this->possymBuf[this->possymReadPos++].sym, &plane);
|
||||
outputCount++;
|
||||
}
|
||||
*outputSymIds = NULLC;
|
||||
if (outputCount <= maxOutputSymIds) {
|
||||
return PICO_OK;
|
||||
} else {
|
||||
return PICO_EXC_BUF_OVERFLOW;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* end picotrns.c */
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picotrns.h
|
||||
*
|
||||
* fst processing
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
/** @addtogroup picotrns
|
||||
*
|
||||
* Conventions:
|
||||
*
|
||||
* - The input to the transducer is a list of pos/sym pairs, where pos are arbitrary position markers
|
||||
* - All positions are allowed on input (in particular all those coming as an output of a previous transduction)
|
||||
* - A phone sequence to be transduced has to begin with PICOKNOW_PHON_START_ID and end with PICOKNOW_PHON_TERM_ID
|
||||
* These special symbols are kept in the transduction output (as first and last symbol)
|
||||
* - Symbols inserted by the transduction process allways get their position marker pos=PICOTRNS_POS_INSERT
|
||||
* - The order of positions on output must be the same as that on input, i.e. apart from inserted pairs, the
|
||||
* output position sequence must be a sub-sequence of the input position sequence.
|
||||
* - Inserted symbols are allways preceded by a positioned pos/sym pair, e.g.
|
||||
* if the sequence pos1/sym1, pos2/sym2 should be tranduced to x/sym3, y/sym4, z/sym5, then x must be pos1 or pos2
|
||||
* and not PICOTRNS_POS_INSERT
|
||||
*
|
||||
* For lingware developers: Insertions are always interpreted "to the right"
|
||||
* - E.g.: The original sequence is phon1 , command , phon2
|
||||
* - The input to the transducer is then pos1/phon1 , pos2/phon2
|
||||
* - The output is pos1/phon1' -1/phon_ins pos2/phon2' [assuming -1 is the special insertion pos]
|
||||
* - Then the new sequence will be recomposed as phon1' , phon_ins , command , phon2' [note position of command!]
|
||||
* - To overwrite this behaviour, rules must be formulated such that the transduction output is
|
||||
* pos1/phon1' pos2/phon_ins -1/phon2'
|
||||
*/
|
||||
#ifndef PICOTRNS_H_
|
||||
#define PICOTRNS_H_
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picokfst.h"
|
||||
#include "picoktab.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
#define PICOTRNS_MAX_NUM_POSSYM 255
|
||||
|
||||
#define PICOTRNS_POS_INSERT (picoos_int16) -1 /* position returned by transducer to mark symbols inserted by the transducer */
|
||||
#define PICOTRNS_POS_INVALID (picoos_int16) -2 /* value to mark an invalid (e.g. uninitiated) position */
|
||||
#define PICOTRNS_POS_IGNORE (picoos_int16) -3 /* value to mark a pos/sym pair to be ignored (e.g. start/term symbols only used by the transducer) */
|
||||
|
||||
|
||||
typedef struct picotrns_possym {
|
||||
picoos_int16 pos;
|
||||
picoos_int16 sym;
|
||||
} picotrns_possym_t;
|
||||
|
||||
picoos_uint8 picotrns_unplane(picoos_int16 symIn, picoos_uint8 * plane);
|
||||
|
||||
|
||||
#if defined(PICO_DEBUG)
|
||||
|
||||
void PICOTRNS_PRINTSYM(picoknow_KnowledgeBase kbdbg, picoos_int16 insym);
|
||||
|
||||
void PICOTRNS_PRINTSYMSEQ(picoknow_KnowledgeBase kbdbg, const picotrns_possym_t seq[], const picoos_uint16 seqLen);
|
||||
|
||||
void picotrns_printSolution(const picotrns_possym_t outSeq[], const picoos_uint16 outSeqLen);
|
||||
|
||||
#else
|
||||
#define PICOTRNS_PRINTSYM(x,y)
|
||||
#define PICOTRNS_PRINTSYMSEQ(x,y,z)
|
||||
#define picotrns_printSolution NULL
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct picotrns_altDesc * picotrns_AltDesc;
|
||||
|
||||
|
||||
picotrns_AltDesc picotrns_allocate_alt_desc_buf(picoos_MemoryManager mm, picoos_uint32 maxByteSize, picoos_uint16 * numAltDescs);
|
||||
|
||||
void picotrns_deallocate_alt_desc_buf(picoos_MemoryManager mm, picotrns_AltDesc * altDescBuf);
|
||||
|
||||
|
||||
/* type of function for printing transduction solutions;
|
||||
only for testing purposes in transduction mode where all solutions
|
||||
are produced */
|
||||
typedef void picotrns_printSolutionFct(const picotrns_possym_t outSeq[], const picoos_uint16 outSeqLen);
|
||||
|
||||
|
||||
|
||||
/** overall transduction; transduces 'inSeq' with 'inSeqLen' elements
|
||||
to '*outSeqLen' elements in 'outSeq';
|
||||
*
|
||||
* @param fst the finite-state transducer used for transduction
|
||||
* @param firstSolOnly determines whether only the first solution (usually)
|
||||
or all solutions should be produced (for testing); only the last found
|
||||
solution is returned in 'outSeq';
|
||||
* @param printSolution if not NULL, every found solution is displayed using
|
||||
the given function
|
||||
* @param inSeq the input sequence
|
||||
* @param inSeqLen the input sequence length
|
||||
* @retval outSeq the output sequence
|
||||
* @retval outSeqLen the output sequence length
|
||||
* @param maxOutSeqLen must provide the maximum length of 'outSeq'
|
||||
* @param altDescBuf must provide a working array of length 'maxAltDescLen'
|
||||
* @param maxAltDescLen should be chosen at least 'maxOutSeqLen' + 1
|
||||
* @retval nrSteps returns the overall internal number of iterative steps done
|
||||
* @return status of the transduction: PICO_OK, if transduction successful
|
||||
@note if 'outSeq' or 'altDesc' are too small to hold a solution,
|
||||
an error occurs and the input is simply transfered to the output
|
||||
(up to maximum possible length)
|
||||
*/
|
||||
extern pico_status_t picotrns_transduce (picokfst_FST fst, picoos_bool firstSolOnly,
|
||||
picotrns_printSolutionFct printSolution,
|
||||
const picotrns_possym_t inSeq[], picoos_uint16 inSeqLen,
|
||||
picotrns_possym_t outSeq[], picoos_uint16 * outSeqLen, picoos_uint16 maxOutSeqLen,
|
||||
picotrns_AltDesc altDescBuf, picoos_uint16 maxAltDescLen,
|
||||
picoos_uint32 *nrSteps);
|
||||
|
||||
|
||||
|
||||
/* transduce 'inSeq' into 'outSeq' 'inSeq' has to be terminated with the id for symbol '#'. 'outSeq' is terminated in the same way. */
|
||||
/*
|
||||
pico_status_t picotrns_transduce_sequence(picokfst_FST fst, const picotrns_possym_t inSeq[], picoos_uint16 inSeqLen,
|
||||
picotrns_possym_t outSeq[], picoos_uint16 * outSeqLen);
|
||||
*/
|
||||
|
||||
/* copy elements from inSeq to outSeq, ignoring elements with epsilon symbol */
|
||||
pico_status_t picotrns_eliminate_epsilons(const picotrns_possym_t inSeq[], picoos_uint16 inSeqLen,
|
||||
picotrns_possym_t outSeq[], picoos_uint16 * outSeqLen, picoos_uint16 maxOutSeqLen);
|
||||
|
||||
/* copy elements from inSeq to outSeq, inserting syllable separators in some trivial way.
|
||||
* inSeq is assumed to be at most, outSeq at least of size PICOTRNS_MAX_NUM_POSSYM */
|
||||
pico_status_t picotrns_trivial_syllabify(picoktab_Phones phones,
|
||||
const picotrns_possym_t inSeq[], const picoos_uint16 inSeqLen,
|
||||
picotrns_possym_t outSeq[], picoos_uint16 * outSeqLen, picoos_uint16 maxOutSeqLen);
|
||||
|
||||
|
||||
/** object : SimpleTransducer
|
||||
* shortcut : st
|
||||
*
|
||||
*/
|
||||
typedef struct picotrns_simple_transducer * picotrns_SimpleTransducer;
|
||||
|
||||
picotrns_SimpleTransducer picotrns_newSimpleTransducer(picoos_MemoryManager mm,
|
||||
picoos_Common common,
|
||||
picoos_uint16 maxAltDescLen);
|
||||
|
||||
pico_status_t picotrns_disposeSimpleTransducer(picotrns_SimpleTransducer * this,
|
||||
picoos_MemoryManager mm);
|
||||
|
||||
pico_status_t picotrns_stInitialize(picotrns_SimpleTransducer transducer);
|
||||
|
||||
pico_status_t picotrns_stAddWithPlane(picotrns_SimpleTransducer this, picoos_char * inStr, picoos_uint8 plane);
|
||||
|
||||
pico_status_t picotrns_stTransduce(picotrns_SimpleTransducer this, picokfst_FST fst);
|
||||
|
||||
pico_status_t picotrns_stGetSymSequence(
|
||||
picotrns_SimpleTransducer this,
|
||||
picoos_uint8 * outputSymIds,
|
||||
picoos_uint32 maxOutputSymIds);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*PICOTRNS_H_*/
|
||||
@@ -0,0 +1,582 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picowa.c
|
||||
*
|
||||
* word analysis PU - lexicon lookup and POS prediction
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picodbg.h"
|
||||
#include "picodata.h"
|
||||
#include "picowa.h"
|
||||
#include "picoklex.h"
|
||||
#include "picokdt.h"
|
||||
#include "picoktab.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
/* PU waStep states */
|
||||
#define WA_STEPSTATE_COLLECT 0
|
||||
#define WA_STEPSTATE_PROCESS 1
|
||||
#define WA_STEPSTATE_FEED 2
|
||||
|
||||
|
||||
/* subobject : WordAnaUnit
|
||||
* shortcut : wa
|
||||
* context size : one item
|
||||
*/
|
||||
typedef struct wa_subobj {
|
||||
picoos_uint8 procState; /* for next processing step decision */
|
||||
|
||||
/* one item only */
|
||||
picoos_uint8 inBuf[PICOWA_MAXITEMSIZE]; /* internal input buffer */
|
||||
picoos_uint16 inBufSize; /* actually allocated size */
|
||||
picoos_uint16 inLen; /* length of item in inBuf, 0 for empty buf */
|
||||
|
||||
picoos_uint8 outBuf[PICOWA_MAXITEMSIZE]; /* internal output buffer */
|
||||
picoos_uint16 outBufSize; /* actually allocated size */
|
||||
picoos_uint16 outLen; /* length of item in outBuf, 0 for empty buf */
|
||||
|
||||
/* lex knowledge base */
|
||||
picoklex_Lex lex;
|
||||
|
||||
/* ulex knowledge bases */
|
||||
picoos_uint8 numUlex;
|
||||
picoklex_Lex ulex[PICOKNOW_MAX_NUM_ULEX];
|
||||
|
||||
/* tab knowledge base */
|
||||
picoktab_Pos tabpos;
|
||||
|
||||
/* dtposp knowledge base */
|
||||
picokdt_DtPosP dtposp;
|
||||
} wa_subobj_t;
|
||||
|
||||
|
||||
static pico_status_t waInitialize(register picodata_ProcessingUnit this, picoos_int32 resetMode) {
|
||||
picoos_uint8 i;
|
||||
picoklex_Lex ulex;
|
||||
wa_subobj_t * wa;
|
||||
|
||||
picoknow_kb_id_t ulexKbIds[PICOKNOW_MAX_NUM_ULEX] = PICOKNOW_KBID_ULEX_ARRAY;
|
||||
|
||||
PICODBG_DEBUG(("calling"));
|
||||
|
||||
if (NULL == this || NULL == this->subObj) {
|
||||
return (picodata_step_result_t) picoos_emRaiseException(this->common->em,
|
||||
PICO_ERR_NULLPTR_ACCESS, NULL, NULL);
|
||||
}
|
||||
wa = (wa_subobj_t *) this->subObj;
|
||||
wa->procState = WA_STEPSTATE_COLLECT;
|
||||
wa->inBufSize = PICOWA_MAXITEMSIZE;
|
||||
wa->inLen = 0;
|
||||
wa->outBufSize = PICOWA_MAXITEMSIZE;
|
||||
wa->outLen = 0;
|
||||
|
||||
if (resetMode == PICO_RESET_SOFT) {
|
||||
/*following initializations needed only at startup or after a full reset*/
|
||||
return PICO_OK;
|
||||
}
|
||||
/* kb lex */
|
||||
wa->lex = picoklex_getLex(this->voice->kbArray[PICOKNOW_KBID_LEX_MAIN]);
|
||||
if (wa->lex == NULL) {
|
||||
return picoos_emRaiseException(this->common->em, PICO_EXC_KB_MISSING,
|
||||
NULL, NULL);
|
||||
}
|
||||
PICODBG_DEBUG(("got lex"));
|
||||
|
||||
/* kb ulex[] */
|
||||
wa->numUlex = 0;
|
||||
for (i = 0; i<PICOKNOW_MAX_NUM_ULEX; i++) {
|
||||
ulex = picoklex_getLex(this->voice->kbArray[ulexKbIds[i]]);
|
||||
if (NULL != ulex) {
|
||||
wa->ulex[wa->numUlex++] = ulex;
|
||||
}
|
||||
}
|
||||
PICODBG_DEBUG(("got %i user lexica", wa->numUlex));
|
||||
|
||||
/* kb tabpos */
|
||||
wa->tabpos =
|
||||
picoktab_getPos(this->voice->kbArray[PICOKNOW_KBID_TAB_POS]);
|
||||
if (wa->tabpos == NULL) {
|
||||
return picoos_emRaiseException(this->common->em, PICO_EXC_KB_MISSING,
|
||||
NULL, NULL);
|
||||
}
|
||||
PICODBG_DEBUG(("got tabpos"));
|
||||
|
||||
/* kb dtposp */
|
||||
wa->dtposp = picokdt_getDtPosP(this->voice->kbArray[PICOKNOW_KBID_DT_POSP]);
|
||||
if (wa->dtposp == NULL) {
|
||||
return picoos_emRaiseException(this->common->em, PICO_EXC_KB_MISSING,
|
||||
NULL, NULL);
|
||||
}
|
||||
PICODBG_DEBUG(("got dtposp"));
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
static picodata_step_result_t waStep(register picodata_ProcessingUnit this,
|
||||
picoos_int16 mode,
|
||||
picoos_uint16 *numBytesOutput);
|
||||
|
||||
static pico_status_t waTerminate(register picodata_ProcessingUnit this) {
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
static pico_status_t waSubObjDeallocate(register picodata_ProcessingUnit this,
|
||||
picoos_MemoryManager mm) {
|
||||
if (NULL != this) {
|
||||
picoos_deallocate(this->common->mm, (void *) &this->subObj);
|
||||
}
|
||||
mm = mm; /* avoid warning "var not used in this function"*/
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
picodata_ProcessingUnit picowa_newWordAnaUnit(picoos_MemoryManager mm,
|
||||
picoos_Common common,
|
||||
picodata_CharBuffer cbIn,
|
||||
picodata_CharBuffer cbOut,
|
||||
picorsrc_Voice voice) {
|
||||
picodata_ProcessingUnit this;
|
||||
|
||||
this = picodata_newProcessingUnit(mm, common, cbIn, cbOut, voice);
|
||||
if (this == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this->initialize = waInitialize;
|
||||
PICODBG_DEBUG(("set this->step to waStep"));
|
||||
this->step = waStep;
|
||||
this->terminate = waTerminate;
|
||||
this->subDeallocate = waSubObjDeallocate;
|
||||
this->subObj = picoos_allocate(mm, sizeof(wa_subobj_t));
|
||||
if (this->subObj == NULL) {
|
||||
picoos_deallocate(mm, (void *)&this);
|
||||
picoos_emRaiseException(common->em, PICO_EXC_OUT_OF_MEM, NULL, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
waInitialize(this, PICO_RESET_FULL);
|
||||
return this;
|
||||
}
|
||||
|
||||
/* ***********************************************************************/
|
||||
/* WORDGRAPH proc functions */
|
||||
/* ***********************************************************************/
|
||||
|
||||
static picoos_uint8 waClassifyPos(register picodata_ProcessingUnit this,
|
||||
register wa_subobj_t *wa,
|
||||
const picoos_uint8 *graph,
|
||||
const picoos_uint16 graphlen) {
|
||||
picokdt_classify_result_t dtres;
|
||||
picoos_uint8 specchar;
|
||||
picoos_uint16 i;
|
||||
|
||||
PICODBG_DEBUG(("graphlen %d", graphlen));
|
||||
|
||||
/* check existence of special char (e.g. hyphen) in graph:
|
||||
for now, check existence of hard-coded ascii hyphen,
|
||||
ie. preproc needs to match all UTF8 hyphens to the ascii
|
||||
hyphen. */
|
||||
/* @todo : consider specifying special char(s) in lingware. */
|
||||
specchar = FALSE;
|
||||
i = 0;
|
||||
while ((i < graphlen) && (!specchar)) {
|
||||
if (graph[i++] == '-') {
|
||||
specchar = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* construct input vector, which is set in dtposp */
|
||||
if (!picokdt_dtPosPconstructInVec(wa->dtposp, graph, graphlen, specchar)) {
|
||||
/* error constructing invec */
|
||||
PICODBG_WARN(("problem with invec"));
|
||||
picoos_emRaiseWarning(this->common->em, PICO_WARN_INVECTOR, NULL, NULL);
|
||||
return PICODATA_ITEMINFO1_ERR;
|
||||
}
|
||||
|
||||
/* classify */
|
||||
if (!picokdt_dtPosPclassify(wa->dtposp)) {
|
||||
/* error doing classification */
|
||||
PICODBG_WARN(("problem classifying"));
|
||||
picoos_emRaiseWarning(this->common->em, PICO_WARN_CLASSIFICATION,
|
||||
NULL, NULL);
|
||||
return PICODATA_ITEMINFO1_ERR;
|
||||
}
|
||||
|
||||
/* decompose */
|
||||
if (!picokdt_dtPosPdecomposeOutClass(wa->dtposp, &dtres)) {
|
||||
/* error decomposing */
|
||||
PICODBG_WARN(("problem decomposing"));
|
||||
picoos_emRaiseWarning(this->common->em, PICO_WARN_OUTVECTOR,
|
||||
NULL, NULL);
|
||||
return PICODATA_ITEMINFO1_ERR;
|
||||
}
|
||||
|
||||
if (dtres.set) {
|
||||
PICODBG_DEBUG(("class %d", dtres.class));
|
||||
return (picoos_uint8)dtres.class;
|
||||
} else {
|
||||
PICODBG_WARN(("result not set"));
|
||||
picoos_emRaiseWarning(this->common->em, PICO_WARN_CLASSIFICATION,
|
||||
NULL, NULL);
|
||||
return PICODATA_ITEMINFO1_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static pico_status_t waProcessWordgraph(register picodata_ProcessingUnit this,
|
||||
register wa_subobj_t *wa /*inout*/,
|
||||
picodata_itemhead_t *head /*inout*/,
|
||||
const picoos_uint8 *content) {
|
||||
pico_status_t status;
|
||||
picoklex_lexl_result_t lexres;
|
||||
picoos_uint8 posbuf[PICOKTAB_MAXNRPOS_IN_COMB];
|
||||
picoos_uint8 i;
|
||||
picoos_uint8 foundIndex;
|
||||
picoos_bool found;
|
||||
|
||||
|
||||
PICODBG_DEBUG(("type %c, len %d", head->type, head->len));
|
||||
|
||||
/* do lookup
|
||||
if no entry found:
|
||||
do POS prediction: -> WORDGRAPH(POSes,NA)graph
|
||||
else:
|
||||
if incl-phone:
|
||||
N entries possible -> WORDINDEX(POSes,NA)POS1|ind1...POSN|indN
|
||||
(N in {1,...,PICOKLEX_MAX_NRRES}, now up to 4)
|
||||
else:
|
||||
no phone, one entry -> WORDGRAPH(POS,NA)graph
|
||||
*/
|
||||
|
||||
found = FALSE;
|
||||
i = 0;
|
||||
while (!found && (i < wa->numUlex)) {
|
||||
found = picoklex_lexLookup(wa->ulex[i], content, head->len, &lexres);
|
||||
i++;
|
||||
}
|
||||
/* note that if found, i will be incremented nevertheless, so i >= 1 */
|
||||
if (found) {
|
||||
foundIndex = i;
|
||||
} else {
|
||||
foundIndex = 0;
|
||||
}
|
||||
if (!found && !picoklex_lexLookup(wa->lex, content, head->len, &lexres)) {
|
||||
/* no lex entry found, WORDGRAPH(POS,NA)graph */
|
||||
if (PICO_OK == picodata_copy_item(wa->inBuf, wa->inLen,
|
||||
wa->outBuf, wa->outBufSize,
|
||||
&wa->outLen)) {
|
||||
wa->inLen = 0;
|
||||
/* predict and modify pos in info1 */
|
||||
if (PICO_OK != picodata_set_iteminfo1(wa->outBuf, wa->outLen,
|
||||
waClassifyPos(this, wa, content, head->len))) {
|
||||
return picoos_emRaiseException(this->common->em,
|
||||
PICO_EXC_BUF_OVERFLOW,NULL,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
} else { /* at least one entry found */
|
||||
PICODBG_DEBUG(("at least one entry found in lexicon %i",foundIndex));
|
||||
if (lexres.phonfound) { /* incl. ind-phone and possibly multi-ent. */
|
||||
if (lexres.nrres > PICOKLEX_MAX_NRRES) {
|
||||
/* not possible with system lexicon, needs to be
|
||||
ensured for user lex too */
|
||||
picoos_emRaiseWarning(this->common->em, PICO_WARN_FALLBACK,NULL,
|
||||
(picoos_char *)"using %d lexicon lookup results",
|
||||
PICOKLEX_MAX_NRRES);
|
||||
lexres.nrres = PICOKLEX_MAX_NRRES;
|
||||
}
|
||||
head->type = PICODATA_ITEM_WORDINDEX;
|
||||
if (lexres.nrres == 1) {
|
||||
head->info1 = lexres.posind[0];
|
||||
} else {
|
||||
/* more than one result, POSgroup info needs to be
|
||||
determined for later POS disambiguation */
|
||||
for (i = 0; i < lexres.nrres; i++) {
|
||||
posbuf[i] = lexres.posind[i * PICOKLEX_POSIND_SIZE];
|
||||
}
|
||||
head->info1 = picoktab_getPosGroup(wa->tabpos, posbuf,
|
||||
lexres.nrres);
|
||||
}
|
||||
head->info2 = foundIndex;
|
||||
head->len = lexres.posindlen;
|
||||
if ((status = picodata_put_itemparts(head, lexres.posind,
|
||||
lexres.posindlen,
|
||||
wa->outBuf, wa->outBufSize,
|
||||
&wa->outLen)) == PICO_OK) {
|
||||
wa->inLen = 0;
|
||||
} else {
|
||||
return picoos_emRaiseException(this->common->em, status,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
} else { /* no phone, :G2P, one entry: WORDGRAPH(POS,NA)graph */
|
||||
if (PICO_OK == picodata_copy_item(wa->inBuf, wa->inLen,
|
||||
wa->outBuf, wa->outBufSize,
|
||||
&wa->outLen)) {
|
||||
wa->inLen = 0;
|
||||
/* set lex pos in info1 */
|
||||
if (PICO_OK != picodata_set_iteminfo1(wa->outBuf, wa->outLen,
|
||||
lexres.posind[0])) {
|
||||
return picoos_emRaiseException(this->common->em,
|
||||
PICO_EXC_BUF_OVERFLOW,
|
||||
NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return PICO_OK;
|
||||
}
|
||||
|
||||
|
||||
/* ***********************************************************************/
|
||||
/* waStep function */
|
||||
/* ***********************************************************************/
|
||||
|
||||
/*
|
||||
collect into internal buffer, process, and then feed to output buffer
|
||||
|
||||
init state: COLLECT ext ext
|
||||
state transitions: in IN OUTout
|
||||
COLLECT | getOneItem ->-1 +1 0 0 | (ATOMIC) -> PROCESS (got item)
|
||||
COLLECT | getOneItem -> 0 0 0 0 | IDLE (got no item)
|
||||
|
||||
PROCESS | procOneItem -> 0 -1 +1 0 | (ATOMIC) -> FEED (proc'ed item)
|
||||
PROCESS | procOneItem -> 0 -1 0 0 | BUSY -> COLLECT (item skipped)
|
||||
|
||||
FEED | putOneItem -> 0 0 -1 +1 | BUSY -> COLLECT (put item)
|
||||
FEED | putOneItem -> 0 0 1 0 | OUT_FULL (put no item)
|
||||
*/
|
||||
|
||||
static picodata_step_result_t waStep(register picodata_ProcessingUnit this,
|
||||
picoos_int16 mode,
|
||||
picoos_uint16 * numBytesOutput) {
|
||||
register wa_subobj_t *wa;
|
||||
pico_status_t rv = PICO_OK;
|
||||
|
||||
if (NULL == this || NULL == this->subObj) {
|
||||
return PICODATA_PU_ERROR;
|
||||
}
|
||||
wa = (wa_subobj_t *) this->subObj;
|
||||
mode = mode; /* avoid warning "var not used in this function"*/
|
||||
*numBytesOutput = 0;
|
||||
while (1) { /* exit via return */
|
||||
PICODBG_DEBUG(("doing state %i, inLen: %d, outLen: %d",
|
||||
wa->procState, wa->inLen, wa->outLen));
|
||||
|
||||
switch (wa->procState) {
|
||||
/* collect state: get item from charBuf and store in
|
||||
* internal inBuf
|
||||
*/
|
||||
case WA_STEPSTATE_COLLECT:
|
||||
if (wa->inLen == 0) { /* is input buffer empty? */
|
||||
picoos_uint16 blen;
|
||||
/* try to get one item */
|
||||
rv = picodata_cbGetItem(this->cbIn, wa->inBuf,
|
||||
wa->inBufSize, &blen);
|
||||
PICODBG_DEBUG(("after getting item, status: %d", rv));
|
||||
if (PICO_OK == rv) {
|
||||
/* we now have one item */
|
||||
wa->inLen = blen;
|
||||
wa->procState = WA_STEPSTATE_PROCESS;
|
||||
/* uncomment next line to split into two steps */
|
||||
/* return PICODATA_PU_ATOMIC; */
|
||||
} else if (PICO_EOF == rv) {
|
||||
/* there was no item in the char buffer */
|
||||
return PICODATA_PU_IDLE;
|
||||
} else if ((PICO_EXC_BUF_UNDERFLOW == rv)
|
||||
|| (PICO_EXC_BUF_OVERFLOW == rv)) {
|
||||
PICODBG_ERROR(("problem getting item"));
|
||||
picoos_emRaiseException(this->common->em, rv,
|
||||
NULL, NULL);
|
||||
return PICODATA_PU_ERROR;
|
||||
} else {
|
||||
PICODBG_ERROR(("problem getting item, unhandled"));
|
||||
picoos_emRaiseException(this->common->em, rv,
|
||||
NULL, NULL);
|
||||
return PICODATA_PU_ERROR;
|
||||
}
|
||||
} else { /* there already is an item in the input buffer */
|
||||
PICODBG_WARN(("item already in input buffer"));
|
||||
picoos_emRaiseWarning(this->common->em,
|
||||
PICO_WARN_PU_IRREG_ITEM, NULL, NULL);
|
||||
wa->procState = WA_STEPSTATE_PROCESS;
|
||||
/* uncomment next to split into two steps */
|
||||
/* return PICODATA_PU_ATOMIC; */
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
/* process state: process item in internal inBuf and put
|
||||
* result in internal outBuf
|
||||
*/
|
||||
case WA_STEPSTATE_PROCESS:
|
||||
|
||||
/* ensure there is an item in inBuf and it is valid */
|
||||
if ((wa->inLen > 0) && picodata_is_valid_item(wa->inBuf,
|
||||
wa->inLen)) {
|
||||
picodata_itemhead_t ihead;
|
||||
picoos_uint8 *icontent;
|
||||
pico_status_t rvP = PICO_OK;
|
||||
|
||||
rv = picodata_get_iteminfo(wa->inBuf, wa->inLen, &ihead,
|
||||
&icontent);
|
||||
if (PICO_OK == rv) {
|
||||
|
||||
switch (ihead.type) {
|
||||
case PICODATA_ITEM_WORDGRAPH:
|
||||
|
||||
if (0 < ihead.len) {
|
||||
rvP = waProcessWordgraph(this, wa, &ihead,
|
||||
icontent);
|
||||
} else {
|
||||
/* else ignore empty WORDGRAPH */
|
||||
wa->inLen = 0;
|
||||
wa->procState = WA_STEPSTATE_COLLECT;
|
||||
return PICODATA_PU_BUSY;
|
||||
}
|
||||
break;
|
||||
case PICODATA_ITEM_OTHER:
|
||||
/* skip item */
|
||||
rvP = PICO_WARN_PU_DISCARD_BUF;
|
||||
break;
|
||||
default:
|
||||
/* copy item unmodified */
|
||||
rvP = picodata_copy_item(wa->inBuf,
|
||||
wa->inLen, wa->outBuf,
|
||||
wa->outBufSize, &wa->outLen);
|
||||
break;
|
||||
}
|
||||
|
||||
if (PICO_OK == rvP) {
|
||||
wa->inLen = 0;
|
||||
wa->procState = WA_STEPSTATE_FEED;
|
||||
/* uncomment next to split into two steps */
|
||||
/* return PICODATA_PU_ATOMIC; */
|
||||
} else if (PICO_WARN_PU_DISCARD_BUF == rvP) {
|
||||
/* discard input buffer and get a new item */
|
||||
PICODBG_INFO(("skipping OTHER item"));
|
||||
/* picoos_emRaiseWarning(this->common->em,
|
||||
PICO_WARN_PU_DISCARD_BUF, NULL, NULL);
|
||||
*/
|
||||
wa->inLen = 0;
|
||||
wa->procState = WA_STEPSTATE_COLLECT;
|
||||
return PICODATA_PU_BUSY;
|
||||
} else {
|
||||
/* PICO_EXC_BUF_OVERFLOW <- overflow in outbuf
|
||||
PICO_ERR_OTHER <- no valid item in inbuf
|
||||
or return from processWordgraph
|
||||
*/
|
||||
PICODBG_ERROR(("problem processing item", rvP));
|
||||
picoos_emRaiseException(this->common->em, rvP,
|
||||
NULL, NULL);
|
||||
return PICODATA_PU_ERROR;
|
||||
}
|
||||
|
||||
} else { /* could not get iteminfo */
|
||||
/* PICO_EXC_BUF_OVERFLOW <- overflow in outbuf
|
||||
PICO_ERR_OTHER <- no valid item in inbuf
|
||||
*/
|
||||
PICODBG_ERROR(("problem getting item info, "
|
||||
"discard buffer content"));
|
||||
wa->inLen = 0;
|
||||
wa->procState = WA_STEPSTATE_COLLECT;
|
||||
picoos_emRaiseException(this->common->em, rv,
|
||||
NULL, NULL);
|
||||
return PICODATA_PU_ERROR;
|
||||
}
|
||||
|
||||
} else if (wa->inLen == 0) { /* no item in inBuf */
|
||||
PICODBG_INFO(("no item in inBuf"));
|
||||
/* wa->inLen = 0;*/
|
||||
wa->procState = WA_STEPSTATE_COLLECT;
|
||||
return PICODATA_PU_BUSY;
|
||||
|
||||
} else { /* no valid item in inBuf */
|
||||
/* bad state/item, discard buffer content */
|
||||
PICODBG_WARN(("no valid item, discard buffer content"));
|
||||
picoos_emRaiseWarning(this->common->em,
|
||||
PICO_WARN_PU_IRREG_ITEM, NULL, NULL);
|
||||
picoos_emRaiseWarning(this->common->em,
|
||||
PICO_WARN_PU_DISCARD_BUF, NULL, NULL);
|
||||
wa->inLen = 0;
|
||||
wa->procState = WA_STEPSTATE_COLLECT;
|
||||
return PICODATA_PU_BUSY;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
/* feed state: copy item in internal outBuf to output charBuf */
|
||||
case WA_STEPSTATE_FEED:
|
||||
|
||||
/* check that item fits in cb should not be needed */
|
||||
rv = picodata_cbPutItem(this->cbOut, wa->outBuf,
|
||||
wa->outLen, numBytesOutput);
|
||||
|
||||
PICODATA_INFO_ITEM(this->voice->kbArray[PICOKNOW_KBID_DBG],
|
||||
(picoos_uint8 *)"wana: ", wa->outBuf,
|
||||
wa->outLen);
|
||||
|
||||
PICODBG_DEBUG(("put item, status: %d", rv));
|
||||
if (PICO_OK == rv) {
|
||||
wa->outLen = 0;
|
||||
wa->procState = WA_STEPSTATE_COLLECT;
|
||||
return PICODATA_PU_BUSY;
|
||||
} else if (PICO_EXC_BUF_OVERFLOW == rv) {
|
||||
PICODBG_INFO(("feeding, overflow, PICODATA_PU_OUT_FULL"));
|
||||
return PICODATA_PU_OUT_FULL;
|
||||
} else if ((PICO_EXC_BUF_UNDERFLOW == rv)
|
||||
|| (PICO_ERR_OTHER == rv)) {
|
||||
PICODBG_WARN(("feeding problem, discarding item"));
|
||||
wa->outLen = 0;
|
||||
wa->procState = WA_STEPSTATE_COLLECT;
|
||||
picoos_emRaiseWarning(this->common->em, rv, NULL,NULL);
|
||||
return PICODATA_PU_BUSY;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
} /* switch */
|
||||
|
||||
} /* while */
|
||||
|
||||
/* should be never reached */
|
||||
PICODBG_ERROR(("reached end of function"));
|
||||
picoos_emRaiseException(this->common->em, PICO_ERR_OTHER, NULL, NULL);
|
||||
return PICODATA_PU_ERROR;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* end */
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
/**
|
||||
* @file picowa.h
|
||||
*
|
||||
* Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
|
||||
* All rights reserved.
|
||||
*
|
||||
* History:
|
||||
* - 2009-04-20 -- initial version
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup picowa
|
||||
* ---------------------------------------------------\n
|
||||
* <b> Pico Word Analysis </b>\n
|
||||
* ---------------------------------------------------\n
|
||||
itemtype, iteminfo1, iteminfo2, content -> TYPE(INFO1,INFO2)content
|
||||
in the following
|
||||
|
||||
items input\n
|
||||
===========
|
||||
|
||||
processed by wa:
|
||||
- WORDGRAPH(NA,NA)graph
|
||||
- OTHER(NA,NA)string
|
||||
|
||||
unprocessed:
|
||||
- all other item types are forwarded through the PU without modification:
|
||||
- PUNC
|
||||
- CMD
|
||||
|
||||
|
||||
minimal input size (before processing starts)\n
|
||||
==================
|
||||
|
||||
processing (ie. lex lookup and POS prediction) is possible with
|
||||
- one item
|
||||
|
||||
|
||||
items processed and output\n
|
||||
==========================
|
||||
|
||||
processing an input WORDGRAPH results in one of the following items:
|
||||
- WORDGRAPH(POSes,NA)graph
|
||||
- graph not in lex, POSes determined with dtree, or
|
||||
- graph in lex - single entry without phone (:G2P), POSes from lex
|
||||
- WORDINDEX(POSes,NA)pos1|ind1...posN|indN
|
||||
- graph in lex - {1,4} entries with phone, pos1...posN from lex,
|
||||
{1,4} lexentries indices in content, POSes combined with map table
|
||||
in klex
|
||||
|
||||
processing an input OTHER results in the item being skipped (in the
|
||||
future this can be extended to e.g. spelling)
|
||||
|
||||
see picotok.h for PUNC and CMD
|
||||
|
||||
- POSes %d
|
||||
- is the superset of all single POS and POS combinations defined
|
||||
in the lingware as unique symbol
|
||||
- graph, len>0, utf8 graphemes, %s
|
||||
- pos1|ind1, pos2|ind2, ..., posN|indN
|
||||
- pos? are the single, unambiguous POS only, one byte %d
|
||||
- ind? are the lexentry indices, three bytes %d %d %d
|
||||
|
||||
|
||||
lexicon (system lexicon, but must also be ensured for user lexica)\n
|
||||
=======
|
||||
|
||||
- POS GRAPH PHON, all mandatory, but
|
||||
- * PHON can be an empty string -> no pronunciation in the resulting TTS output
|
||||
- * PHON can be :G2P -> use G2P later to add pronunciation
|
||||
- (POS,GRAPH) is a uniq key (only one entry allowed)
|
||||
- (GRAPH) is almost a uniq key (2-4 entries with the same GRAPH, and
|
||||
differing POS and differing PHON possible)
|
||||
- for one graph we can have 2-4 solutions from the lex which all
|
||||
need to be passed on the the next PU
|
||||
- in this case GRAPH, POS, and PHON all must be available in lex
|
||||
- in this case for each entry only a non-ambiguous, unique POS ID
|
||||
is possible)
|
||||
|
||||
other limitations\n
|
||||
=================
|
||||
|
||||
- item size: header plus len=256 (valid for Pico in general)
|
||||
- wa uses one item context only -> internal buffer set to 256+4
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PICOWA_H_
|
||||
#define PICOWA_H_
|
||||
|
||||
#include "picoos.h"
|
||||
#include "picodata.h"
|
||||
#include "picorsrc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* maximum length of an item incl. head for input and output buffers */
|
||||
#define PICOWA_MAXITEMSIZE 260
|
||||
|
||||
|
||||
picodata_ProcessingUnit picowa_newWordAnaUnit(
|
||||
picoos_MemoryManager mm,
|
||||
picoos_Common common,
|
||||
picodata_CharBuffer cbIn,
|
||||
picodata_CharBuffer cbOut,
|
||||
picorsrc_Voice voice);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*PICOWA_H_*/
|
||||
Reference in New Issue
Block a user