diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/export/talk.h | 34 | ||||
-rw-r--r-- | firmware/mpeg.c | 4 | ||||
-rw-r--r-- | firmware/talk.c | 209 |
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 | |||
29 | void talk_init(void); | ||
30 | int talk_buffer_steal(void); /* claim the mp3 buffer e.g. for play/record */ | ||
31 | int talk_id(int id, bool block); /* play a voice ID from voicefont */ | ||
32 | int 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" | ||
32 | extern 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 | |||
41 | struct 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 | |||
47 | struct 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 | |||
59 | static unsigned char* p_thumbnail; /* buffer for thumbnail */ | ||
60 | static long size_for_thumbnail; /* leftover buffer size for it */ | ||
61 | static struct voicefont* p_voicefont; /* loaded voicefont */ | ||
62 | static bool has_voicefont; /* a voicefont file is present */ | ||
63 | static bool is_playing; /* we're currently playing */ | ||
64 | |||
65 | |||
66 | |||
67 | /***************** Private implementation *****************/ | ||
68 | |||
69 | static 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 */ | ||
111 | void 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 | |||
121 | void 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 */ | ||
129 | int 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 */ | ||
142 | int 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 */ | ||
175 | int 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 | } | ||