ru_tts

Форк
0
/
sink.c 
98 строк · 2.5 Кб
1
/* sink.c -- Interactions with general data consuming callback
2
 *
3
 * Copyright (C) 1990, 1991 Speech Research Laboratory, Minsk
4
 * Copyright (C) 2005 Igor Poretsky <poretsky@mlbox.ru>
5
 * Copyright (C) 2021 Boris Lobanov <lobbormef@gmail.com>
6
 * Copyright (C) 2021 Alexander Ivanov <ivalex01@gmail.com>
7
 *
8
 * SPDX-License-Identifier: MIT
9
 */
10

11
#include <stdint.h>
12
#include <stdlib.h>
13
#include <string.h>
14

15
#include "ru_tts.h"
16
#include "sink.h"
17

18

19
/* Initialize sink control structure */
20
void sink_setup(sink_t *consumer, void *buffer, size_t bufsize, ru_tts_callback function, void *user_data)
21
{
22
  consumer->buffer = buffer;
23
  consumer->buffer_offset = 0;
24
  consumer->bufsize = bufsize;
25
  consumer->status = 0;
26
  consumer->user_data = user_data;
27
  consumer->function = function;
28
  consumer->custom_reset = NULL;
29
}
30

31
/*
32
 * Reset action.
33
 *
34
 * Performs custom reset function if specified.
35
 * Otherwise simply resets buffer offset.
36
 */
37
void sink_reset(sink_t *consumer)
38
{
39
  if (consumer->custom_reset)
40
    consumer->custom_reset(consumer);
41
  else consumer->buffer_offset = 0;
42
}
43

44
/* Pass data to the sink function */
45
void sink_flush(sink_t *consumer)
46
{
47
  if (consumer->function && consumer->buffer && consumer->buffer_offset)
48
    consumer->status |= consumer->function(consumer->buffer, consumer->buffer_offset, consumer->user_data);
49
  sink_reset(consumer);
50
}
51

52
/* Pass one byte of data */
53
void sink_put(sink_t *consumer, int8_t byte)
54
{
55
  ((int8_t *)(consumer->buffer))[consumer->buffer_offset++] = byte;
56
  if (consumer->buffer_offset >= consumer->bufsize)
57
    sink_flush(consumer);
58
}
59

60
/*
61
 * Pass a block of data.
62
 *
63
 * Potentially may cause buffer overflow since this condition
64
 * is not checked during data transfer, but only afterwards.
65
 */
66
void sink_write(sink_t *consumer, const uint8_t *block, size_t size)
67
{
68
  memcpy((uint8_t *)consumer->buffer + consumer->buffer_offset, block, size);
69
  consumer->buffer_offset += size;
70
  if (consumer->buffer_offset >= consumer->bufsize)
71
    sink_flush(consumer);
72
}
73

74
/* Forget last byte if possible */
75
void sink_back(sink_t *consumer)
76
{
77
  if (consumer->buffer_offset)
78
    consumer->buffer_offset--;
79
}
80

81
/*
82
 * Replace the last byte in the consumer buffer.
83
 * If the buffer is empty, acts just like sink_put().
84
 */
85
void sink_replace(sink_t *consumer, uint8_t byte)
86
{
87
  sink_back(consumer);
88
  sink_put(consumer, byte);
89
}
90

91
/*
92
 * Get last byte value from the consumer buffer.
93
 * Returns -1 if the buffer is empty.
94
 */
95
int sink_last(sink_t *consumer)
96
{
97
  return (consumer->buffer_offset) ? ((uint8_t *)(consumer->buffer))[consumer->buffer_offset - 1] : -1;
98
}
99

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.