summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libpcm/adpcm_seek.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libpcm/adpcm_seek.c')
-rw-r--r--lib/rbcodec/codecs/libpcm/adpcm_seek.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libpcm/adpcm_seek.c b/lib/rbcodec/codecs/libpcm/adpcm_seek.c
new file mode 100644
index 0000000000..ce49d5fcd3
--- /dev/null
+++ b/lib/rbcodec/codecs/libpcm/adpcm_seek.c
@@ -0,0 +1,101 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Yoshihisa Uchida
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "adpcm_seek.h"
22#include "codeclib.h"
23
24/*
25 * The helper functions in order to seek for the adpcm codec
26 * which does not include the header each the data block.
27 */
28
29#define MAX_STORE_COUNT 1000
30
31static struct adpcm_data seek_table[MAX_STORE_COUNT];
32static int seek_count;
33static int cur_count;
34static int max_ratio;
35static int cur_ratio;
36
37void init_seek_table(uint32_t max_count)
38{
39 int i = 0;
40
41 for ( ; i < MAX_STORE_COUNT; i++)
42 {
43 seek_table[i].is_valid = false;
44 }
45 seek_count = max_count / MAX_STORE_COUNT + 1;
46 max_ratio = max_count / seek_count + 1;
47 cur_count = 0;
48 cur_ratio = -1;
49}
50
51void add_adpcm_data(struct adpcm_data *data)
52{
53 if (--cur_count <= 0)
54 {
55 cur_count = seek_count;
56 if (++cur_ratio >= max_ratio)
57 cur_ratio = max_ratio - 1;
58
59 if (!seek_table[cur_ratio].is_valid)
60 {
61 seek_table[cur_ratio].pcmdata[0] = data->pcmdata[0];
62 seek_table[cur_ratio].pcmdata[1] = data->pcmdata[1];
63 seek_table[cur_ratio].step[0] = data->step[0];
64 seek_table[cur_ratio].step[1] = data->step[1];
65 seek_table[cur_ratio].is_valid = true;
66 }
67 }
68}
69
70uint32_t seek(uint32_t count, struct adpcm_data *seek_data,
71 uint8_t *(*read_buffer)(size_t *realsize),
72 int (*decode)(const uint8_t *inbuf, size_t inbufsize))
73{
74 int new_ratio = count / seek_count;
75
76 if (new_ratio >= max_ratio)
77 new_ratio = max_ratio - 1;
78
79 if (!seek_table[new_ratio].is_valid)
80 {
81 uint8_t *buffer;
82 size_t n;
83
84 do
85 {
86 buffer = read_buffer(&n);
87 if (n == 0)
88 break;
89 decode(buffer, n);
90 } while (cur_ratio < new_ratio);
91 }
92
93 seek_data->pcmdata[0] = seek_table[new_ratio].pcmdata[0];
94 seek_data->pcmdata[1] = seek_table[new_ratio].pcmdata[1];
95 seek_data->step[0] = seek_table[new_ratio].step[0];
96 seek_data->step[1] = seek_table[new_ratio].step[1];
97
98 cur_ratio = new_ratio;
99 cur_count = seek_count;
100 return cur_ratio * seek_count;
101}