summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorJörg Hohensohn <hohensoh@rockbox.org>2004-03-19 22:15:53 +0000
committerJörg Hohensohn <hohensoh@rockbox.org>2004-03-19 22:15:53 +0000
commitfa97f161abc45bfd5db86bceb8803d2661e65447 (patch)
tree1e06ac8c47bd9165e46e85235f059372ddad2b90 /firmware
parent239b70fad38be55075dd14ea8e3c0f6f54a1f35b (diff)
downloadrockbox-fa97f161abc45bfd5db86bceb8803d2661e65447.tar.gz
rockbox-fa97f161abc45bfd5db86bceb8803d2661e65447.zip
Third step of the voice-UI: numerical settings are spoken (composed at runtime), needs new voicefont at the new location ".rockbox/langs/english.voice"
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4414 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/export/talk.h34
-rw-r--r--firmware/mpeg.c4
-rw-r--r--firmware/talk.c209
3 files changed, 0 insertions, 247 deletions
diff --git a/firmware/export/talk.h b/firmware/export/talk.h
deleted file mode 100644
index b2af46f15e..0000000000
--- a/firmware/export/talk.h
+++ /dev/null
@@ -1,34 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2004 Jörg Hohensohn
11 *
12 * This module collects the Talkbox and voice UI functions.
13 * (Talkbox reads directory names from mp3 clips called thumbnails,
14 * the voice UI lets menus and screens "talk" from a voicefont in memory.
15 *
16 * All files in this archive are subject to the GNU General Public License.
17 * See the file COPYING in the source tree root for full license agreement.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24#ifndef __TALK_H__
25#define __TALK_H__
26
27#include <stdbool.h>
28
29void talk_init(void);
30int talk_buffer_steal(void); /* claim the mp3 buffer e.g. for play/record */
31int talk_id(int id, bool block); /* play a voice ID from voicefont */
32int talk_file(char* filename, bool block); /* play a thumbnail from file */
33
34#endif /* __TALK_H__ */
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index fcb0d54bb7..ff545f03d0 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -30,7 +30,6 @@
30#include "mp3data.h" 30#include "mp3data.h"
31#include "buffer.h" 31#include "buffer.h"
32#include "mp3_playback.h" 32#include "mp3_playback.h"
33#include "talk.h"
34#ifndef SIMULATOR 33#ifndef SIMULATOR
35#include "i2c.h" 34#include "i2c.h"
36#include "mas.h" 35#include "mas.h"
@@ -2135,7 +2134,6 @@ void mpeg_record(char *filename)
2135 recording_filename[MAX_PATH - 1] = 0; 2134 recording_filename[MAX_PATH - 1] = 0;
2136 2135
2137 disable_xing_header = false; 2136 disable_xing_header = false;
2138 talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
2139 queue_post(&mpeg_queue, MPEG_RECORD, NULL); 2137 queue_post(&mpeg_queue, MPEG_RECORD, NULL);
2140} 2138}
2141 2139
@@ -2150,7 +2148,6 @@ static void start_prerecording(void)
2150 prerecord_timeout = current_tick + HZ; 2148 prerecord_timeout = current_tick + HZ;
2151 memset(prerecord_buffer, 0, sizeof(prerecord_buffer)); 2149 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2152 reset_mp3_buffer(); 2150 reset_mp3_buffer();
2153 talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
2154 2151
2155 is_prerecording = true; 2152 is_prerecording = true;
2156 2153
@@ -2407,7 +2404,6 @@ void mpeg_play(int offset)
2407#else 2404#else
2408 is_playing = true; 2405 is_playing = true;
2409 2406
2410 talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
2411 queue_post(&mpeg_queue, MPEG_PLAY, (void*)offset); 2407 queue_post(&mpeg_queue, MPEG_PLAY, (void*)offset);
2412#endif /* #ifdef SIMULATOR */ 2408#endif /* #ifdef SIMULATOR */
2413 2409
diff --git a/firmware/talk.c b/firmware/talk.c
deleted file mode 100644
index d02a4efd7f..0000000000
--- a/firmware/talk.c
+++ /dev/null
@@ -1,209 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2004 Jörg Hohensohn
11 *
12 * This module collects the Talkbox and voice UI functions.
13 * (Talkbox reads directory names from mp3 clips called thumbnails,
14 * the voice UI lets menus and screens "talk" from a voicefont in memory.
15 *
16 * All files in this archive are subject to the GNU General Public License.
17 * See the file COPYING in the source tree root for full license agreement.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24#include <stdio.h>
25#include <stddef.h>
26#include "file.h"
27#include "buffer.h"
28#include "kernel.h"
29#include "mp3_playback.h"
30#include "mpeg.h"
31#include "talk.h"
32extern void bitswap(unsigned char *data, int length); /* no header for this */
33
34/***************** Constants *****************/
35
36#define VOICEFONT_FILENAME "/.rockbox/voicefont"
37
38
39/***************** Data types *****************/
40
41struct clip_entry /* one entry of the index table */
42{
43 int offset; /* offset from start of voicefont file */
44 int size; /* size of the clip */
45};
46
47struct voicefont /* file format of our "voicefont" */
48{
49 int version; /* version of the voicefont */
50 int headersize; /* size of the header, =offset to index */
51 int id_max; /* number of clips contained */
52 struct clip_entry index[]; /* followed by the index table */
53 /* and finally the bitswapped mp3 clips, not visible here */
54};
55
56
57/***************** Globals *****************/
58
59static unsigned char* p_thumbnail; /* buffer for thumbnail */
60static long size_for_thumbnail; /* leftover buffer size for it */
61static struct voicefont* p_voicefont; /* loaded voicefont */
62static bool has_voicefont; /* a voicefont file is present */
63static bool is_playing; /* we're currently playing */
64
65
66
67/***************** Private implementation *****************/
68
69static int load_voicefont(void)
70{
71 int fd;
72 int size;
73
74 p_voicefont = NULL; /* indicate no voicefont if we fail below */
75
76 fd = open(VOICEFONT_FILENAME, O_RDONLY);
77 if (fd < 0) /* failed to open */
78 {
79 p_voicefont = NULL; /* indicate no voicefont */
80 has_voicefont = false; /* don't try again */
81 return 0;
82 }
83
84 size = read(fd, mp3buf, mp3end - mp3buf);
85 if (size > 1000
86 && ((struct voicefont*)mp3buf)->headersize
87 == offsetof(struct voicefont, index))
88 {
89 p_voicefont = (struct voicefont*)mp3buf;
90
91 /* thumbnail buffer is the remaining space behind */
92 p_thumbnail = mp3buf + size;
93 p_thumbnail += (int)p_thumbnail % 2; /* 16-bit align */
94 size_for_thumbnail = mp3end - p_thumbnail;
95
96 /* max. DMA size, fixme */
97 if (size_for_thumbnail > 0xFFFF)
98 size_for_thumbnail = 0xFFFF;
99 }
100 else
101 {
102 has_voicefont = false; /* don't try again */
103 }
104 close(fd);
105
106 return size;
107}
108
109
110/* called in ISR context if mp3 data got consumed */
111void mp3_callback(unsigned char** start, int* size)
112{
113 (void)start; /* unused parameter, avoid warning */
114 *size = 0; /* end of data */
115 is_playing = false;
116 mp3_play_stop(); /* fixme: should be done by caller */
117}
118
119/***************** Public implementation *****************/
120
121void talk_init(void)
122{
123 has_voicefont = true; /* unless we fail later, assume we have one */
124 talk_buffer_steal();
125}
126
127
128/* somebody else claims the mp3 buffer, e.g. for regular play/record */
129int talk_buffer_steal(void)
130{
131 p_voicefont = NULL; /* indicate no voicefont (trashed) */
132 p_thumbnail = mp3buf; /* whole space for thumbnail */
133 size_for_thumbnail = mp3end - mp3buf;
134 /* max. DMA size, fixme */
135 if (size_for_thumbnail > 0xFFFF)
136 size_for_thumbnail = 0xFFFF;
137 return 0;
138}
139
140
141/* play a voice ID from voicefont */
142int talk_id(int id, bool block)
143{
144 int clipsize;
145
146 if (mpeg_status()) /* busy, buffer in use */
147 return -1;
148
149 if (p_voicefont == NULL && has_voicefont)
150 load_voicefont(); /* reload needed */
151
152 if (p_voicefont == NULL) /* still no voices? */
153 return -1;
154
155 if (id >= p_voicefont->id_max)
156 return -1;
157
158 clipsize = p_voicefont->index[id].size;
159 if (clipsize == 0) /* clip not included in voicefont */
160 return -1;
161
162 is_playing = true;
163 mp3_play_data(mp3buf + p_voicefont->index[id].offset,
164 clipsize, mp3_callback);
165 mp3_play_pause(true); /* kickoff audio */
166
167 while(block && is_playing)
168 sleep(1);
169
170 return 0;
171}
172
173
174/* play a thumbnail from file */
175int talk_file(char* filename, bool block)
176{
177 int fd;
178 int size;
179
180 if (mpeg_status()) /* busy, buffer in use */
181 return -1;
182
183 if (p_thumbnail == NULL || size_for_thumbnail <= 0)
184 return -1;
185
186 fd = open(filename, O_RDONLY);
187 if (fd < 0) /* failed to open */
188 {
189 return 0;
190 }
191
192 size = read(fd, p_thumbnail, size_for_thumbnail);
193 close(fd);
194
195 /* ToDo: find audio, skip ID headers and trailers */
196
197 if (size)
198 {
199 bitswap(p_thumbnail, size);
200 is_playing = true;
201 mp3_play_data(p_thumbnail, size, mp3_callback);
202 mp3_play_pause(true); /* kickoff audio */
203
204 while(block && is_playing)
205 sleep(1);
206 }
207
208 return size;
209}