annotate decoders/voc.c @ 474:c66080364dff

Most decoders now report total sample play time, now. Technically, this breaks binary compatibility with the 1.0 branch, since it extends the Sound_Sample struct, but most (all?) programs are just passing pointers allocated by SDL_sound around, and might be okay. Source-level compatibility is not broken...yet! :) --ryan. -------- Original Message -------- Subject: SDL_sound patch: Finding total length of time of sound file. Date: Sun, 26 Jan 2003 09:31:17 -0800 (PST) Hi Ryan, I am working with Eric Wing and helping him modify SDL_sound. AS part of our efforts in improving and enhancing SDL_sound, we like to submit this patch. We modified the codecs to find the total time of a sound file. Below is the explanation of the patch. The patch is appended as an attachment to this email. * MOTIVATION: We needed the ability to get the total play time of a sample (And we noticed that we're not the only ones). Since SDL_sound blocks direct access to the specific decoders, there is no way for a user to know this information short of decoding the whole thing. Because of this, we believe this will be a useful addition, even though the accuracy may not be perfect (subject to each decoder) or the information may not always be available. * CONTRIBUTORS: Wesley Leong (modified the majority of the codecs and verified the results) Eric Wing (showed everyone how to do modify codec, modified mikmod) Wang Lam (modified a handful of codecs, researched into specs and int overflow) Ahilan Anantha (modified a few codecs and helped with integer math) * GENERAL ISSUES: We chose the value to be milliseconds as an Sint32. Milliseconds because that's what Sound_Seek takes as a parameter and -1 to allow for instances/codecs where the value could not be determined. We are not sure if this is the final convention you want, so we are willing to work with you on this. We also expect the total_time field to be set on open and never again modified by SDL_sound. Users may access it directly much like the sample buffer and buffer_size. We thought about recomputing the time on DecodeAll, but since users may seek or decode small chunks first, not all the data may be there. So this is better done by the user. This may be good information to document. Currently, all the main codecs are implemented except for QuickTime.
author Ryan C. Gordon <icculus@icculus.org>
date Sat, 08 May 2004 08:19:50 +0000
parents cd46c97e58bc
children 3e705c9180e5
rev   line source
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
1 /*
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
2 * SDL_sound -- An abstract sound format decoding API.
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
3 * Copyright (C) 2001 Ryan C. Gordon.
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
4 *
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
8 * version 2.1 of the License, or (at your option) any later version.
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
9 *
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
13 * Lesser General Public License for more details.
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
14 *
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
18 */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
19
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
20 /*
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
21 * VOC decoder for SDL_sound.
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
22 *
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
23 * This driver handles Creative Labs VOC audio data...this is a legacy format,
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
24 * but there's some game ports that could make use of such a decoder. Plus,
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
25 * VOC is fairly straightforward to decode, so this is a more complex, but
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
26 * still palatable example of an SDL_sound decoder. Y'know, in case the
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
27 * RAW decoder didn't do it for you. :)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
28 *
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
29 * This code was ripped from a decoder I had written for SDL_mixer, which was
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
30 * largely ripped from sox v12.17.1's voc.c.
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
31 *
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
32 * SDL_mixer: http://www.libsdl.org/projects/SDL_mixer/
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
33 * sox: http://www.freshmeat.net/projects/sox/
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
34 *
184
47cc2de2ae36 Changed reference to "LICENSE" file to "COPYING".
Ryan C. Gordon <icculus@icculus.org>
parents: 149
diff changeset
35 * Please see the file COPYING in the source's root directory.
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
36 *
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
37 * This file written by Ryan C. Gordon. (icculus@clutteredmind.org)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
38 */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
39
106
40de367eb59e Changing my include structure to do this right.
Ryan C. Gordon <icculus@icculus.org>
parents: 104
diff changeset
40 #if HAVE_CONFIG_H
40de367eb59e Changing my include structure to do this right.
Ryan C. Gordon <icculus@icculus.org>
parents: 104
diff changeset
41 # include <config.h>
40de367eb59e Changing my include structure to do this right.
Ryan C. Gordon <icculus@icculus.org>
parents: 104
diff changeset
42 #endif
100
6d9fdec2f708 added config.h, added --enable-debug flag, various other changes to the build system
fingolfin
parents: 64
diff changeset
43
114
dd95a12539fd Changed an #if defined to #ifdef, for consistency with the other
Ryan C. Gordon <icculus@icculus.org>
parents: 106
diff changeset
44 #ifdef SOUND_SUPPORTS_VOC
104
103cfcb3c014 Updated to fix build system problem.
Ryan C. Gordon <icculus@icculus.org>
parents: 100
diff changeset
45
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
46 #include <stdio.h>
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
47 #include <stdlib.h>
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
48 #include <string.h>
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
49
106
40de367eb59e Changing my include structure to do this right.
Ryan C. Gordon <icculus@icculus.org>
parents: 104
diff changeset
50 #include "SDL_sound.h"
40de367eb59e Changing my include structure to do this right.
Ryan C. Gordon <icculus@icculus.org>
parents: 104
diff changeset
51
40de367eb59e Changing my include structure to do this right.
Ryan C. Gordon <icculus@icculus.org>
parents: 104
diff changeset
52 #define __SDL_SOUND_INTERNAL__
40de367eb59e Changing my include structure to do this right.
Ryan C. Gordon <icculus@icculus.org>
parents: 104
diff changeset
53 #include "SDL_sound_internal.h"
40de367eb59e Changing my include structure to do this right.
Ryan C. Gordon <icculus@icculus.org>
parents: 104
diff changeset
54
47
ea58bc3b15d7 Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents: 32
diff changeset
55 static int VOC_init(void);
ea58bc3b15d7 Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents: 32
diff changeset
56 static void VOC_quit(void);
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
57 static int VOC_open(Sound_Sample *sample, const char *ext);
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
58 static void VOC_close(Sound_Sample *sample);
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
59 static Uint32 VOC_read(Sound_Sample *sample);
221
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
60 static int VOC_rewind(Sound_Sample *sample);
306
c97be6e1bd27 Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents: 301
diff changeset
61 static int VOC_seek(Sound_Sample *sample, Uint32 ms);
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
62
149
1df5c106504e Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents: 114
diff changeset
63 static const char *extensions_voc[] = { "VOC", NULL };
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
64 const Sound_DecoderFunctions __Sound_DecoderFunctions_VOC =
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
65 {
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
66 {
149
1df5c106504e Decoders can now list multiple file extensions.
Ryan C. Gordon <icculus@icculus.org>
parents: 114
diff changeset
67 extensions_voc,
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
68 "Creative Labs Voice format",
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
69 "Ryan C. Gordon <icculus@clutteredmind.org>",
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
70 "http://www.icculus.org/SDL_sound/"
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
71 },
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
72
221
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
73 VOC_init, /* init() method */
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
74 VOC_quit, /* quit() method */
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
75 VOC_open, /* open() method */
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
76 VOC_close, /* close() method */
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
77 VOC_read, /* read() method */
306
c97be6e1bd27 Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents: 301
diff changeset
78 VOC_rewind, /* rewind() method */
c97be6e1bd27 Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents: 301
diff changeset
79 VOC_seek /* seek() method */
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
80 };
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
81
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
82
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
83 /* Private data for VOC file */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
84 typedef struct vocstuff {
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
85 Uint32 rest; /* bytes remaining in current block */
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
86 Uint32 rate; /* rate code (byte) of this chunk */
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
87 int silent; /* sound or silence? */
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
88 Uint32 srate; /* rate code (byte) of silence */
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
89 Uint32 blockseek; /* start of current output block */
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
90 Uint32 samples; /* number of samples output */
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
91 Uint32 size; /* word length of data */
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
92 Uint8 channels; /* number of sound channels */
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
93 int extended; /* Has an extended block been read? */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
94 Uint32 bufpos; /* byte position in internal->buffer. */
224
1bafef18dabf Implemented rewind method.
Ryan C. Gordon <icculus@icculus.org>
parents: 221
diff changeset
95 Uint32 start_pos; /* offset to seek to in stream when rewinding. */
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
96 int error; /* error condition (as opposed to EOF). */
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
97 } vs_t;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
98
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
99
62
b13fafb976be Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents: 47
diff changeset
100 /* Size field */
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
101 /* SJB: note that the 1st 3 are sometimes used as sizeof(type) */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
102 #define ST_SIZE_BYTE 1
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
103 #define ST_SIZE_8BIT 1
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
104 #define ST_SIZE_WORD 2
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
105 #define ST_SIZE_16BIT 2
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
106 #define ST_SIZE_DWORD 4
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
107 #define ST_SIZE_32BIT 4
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
108 #define ST_SIZE_FLOAT 5
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
109 #define ST_SIZE_DOUBLE 6
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
110 #define ST_SIZE_IEEE 7 /* IEEE 80-bit floats. */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
111
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
112 /* Style field */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
113 #define ST_ENCODING_UNSIGNED 1 /* unsigned linear: Sound Blaster */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
114 #define ST_ENCODING_SIGN2 2 /* signed linear 2's comp: Mac */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
115 #define ST_ENCODING_ULAW 3 /* U-law signed logs: US telephony, SPARC */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
116 #define ST_ENCODING_ALAW 4 /* A-law signed logs: non-US telephony */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
117 #define ST_ENCODING_ADPCM 5 /* Compressed PCM */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
118 #define ST_ENCODING_IMA_ADPCM 6 /* Compressed PCM */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
119 #define ST_ENCODING_GSM 7 /* GSM 6.10 33-byte frame lossy compression */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
120
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
121 #define VOC_TERM 0
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
122 #define VOC_DATA 1
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
123 #define VOC_CONT 2
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
124 #define VOC_SILENCE 3
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
125 #define VOC_MARKER 4
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
126 #define VOC_TEXT 5
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
127 #define VOC_LOOP 6
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
128 #define VOC_LOOPEND 7
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
129 #define VOC_EXTENDED 8
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
130 #define VOC_DATA_16 9
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
131
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
132
47
ea58bc3b15d7 Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents: 32
diff changeset
133 static int VOC_init(void)
ea58bc3b15d7 Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents: 32
diff changeset
134 {
ea58bc3b15d7 Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents: 32
diff changeset
135 return(1); /* always succeeds. */
ea58bc3b15d7 Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents: 32
diff changeset
136 } /* VOC_init */
ea58bc3b15d7 Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents: 32
diff changeset
137
ea58bc3b15d7 Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents: 32
diff changeset
138
ea58bc3b15d7 Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents: 32
diff changeset
139 static void VOC_quit(void)
ea58bc3b15d7 Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents: 32
diff changeset
140 {
ea58bc3b15d7 Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents: 32
diff changeset
141 /* it's a no-op. */
ea58bc3b15d7 Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents: 32
diff changeset
142 } /* VOC_quit */
ea58bc3b15d7 Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents: 32
diff changeset
143
ea58bc3b15d7 Added init() and quit() methods.
Ryan C. Gordon <icculus@icculus.org>
parents: 32
diff changeset
144
401
c42ac9ee2ce4 Fixed "inline" keyword to compile.
Ryan C. Gordon <icculus@icculus.org>
parents: 387
diff changeset
145 static __inline__ int voc_readbytes(SDL_RWops *src, vs_t *v, void *p, int size)
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
146 {
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
147 if (SDL_RWread(src, p, size, 1) != 1)
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
148 {
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
149 v->error = 1;
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
150 BAIL_MACRO("VOC: i/o error", 0);
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
151 } /* if */
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
152
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
153 return(1);
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
154 } /* voc_readbytes */
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
155
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
156
401
c42ac9ee2ce4 Fixed "inline" keyword to compile.
Ryan C. Gordon <icculus@icculus.org>
parents: 387
diff changeset
157 static __inline__ int voc_check_header(SDL_RWops *src)
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
158 {
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
159 /* VOC magic header */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
160 Uint8 signature[20]; /* "Creative Voice File\032" */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
161 Uint16 datablockofs;
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
162 vs_t v; /* dummy struct for voc_readbytes */
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
163
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
164 if (!voc_readbytes(src, &v, signature, sizeof (signature)))
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
165 return(0);
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
166
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
167 if (memcmp(signature, "Creative Voice File\032", sizeof (signature)) != 0)
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
168 {
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
169 BAIL_MACRO("VOC: Wrong signature; not a VOC file.", 0);
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
170 } /* if */
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
171
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
172 /* get the offset where the first datablock is located */
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
173 if (!voc_readbytes(src, &v, &datablockofs, sizeof (Uint16)))
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
174 return(0);
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
175
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
176 datablockofs = SDL_SwapLE16(datablockofs);
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
177
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
178 if (SDL_RWseek(src, datablockofs, SEEK_SET) != datablockofs)
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
179 {
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
180 BAIL_MACRO("VOC: Failed to seek to data block.", 0);
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
181 } /* if */
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
182
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
183 return(1); /* success! */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
184 } /* voc_check_header */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
185
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
186
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
187 /* Read next block header, save info, leave position at start of data */
468
cd46c97e58bc Fixed broken VOC decoder...would always dereference NULL during VOC_open().
Ryan C. Gordon <icculus@icculus.org>
parents: 449
diff changeset
188 static int voc_get_block(Sound_Sample *sample, vs_t *v)
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
189 {
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
190 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
191 SDL_RWops *src = internal->rw;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
192 Uint8 bits24[3];
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
193 Uint8 uc, block;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
194 Uint32 sblen;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
195 Uint16 new_rate_short;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
196 Uint32 new_rate_long;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
197 Uint8 trash[6];
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
198 Uint16 period;
474
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 468
diff changeset
199 Uint32 bytes_per_second;
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
200 int i;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
201
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
202 v->silent = 0;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
203 while (v->rest == 0)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
204 {
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
205 if (SDL_RWread(src, &block, sizeof (block), 1) != 1)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
206 return 1; /* assume that's the end of the file. */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
207
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
208 if (block == VOC_TERM)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
209 return 1;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
210
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
211 if (SDL_RWread(src, bits24, sizeof (bits24), 1) != 1)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
212 return 1; /* assume that's the end of the file. */
62
b13fafb976be Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents: 47
diff changeset
213
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
214 /* Size is an 24-bit value. Ugh. */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
215 sblen = ( (bits24[0]) | (bits24[1] << 8) | (bits24[2] << 16) );
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
216
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
217 switch(block)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
218 {
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
219 case VOC_DATA:
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
220 if (!voc_readbytes(src, v, &uc, sizeof (uc)))
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
221 return 0;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
222
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
223 /* When DATA block preceeded by an EXTENDED */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
224 /* block, the DATA blocks rate value is invalid */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
225 if (!v->extended)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
226 {
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
227 BAIL_IF_MACRO(uc == 0, "VOC: Sample rate is zero?", 0);
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
228
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
229 if ((v->rate != -1) && (uc != v->rate))
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
230 BAIL_MACRO("VOC sample rate codes differ", 0);
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
231
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
232 v->rate = uc;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
233 sample->actual.rate = 1000000.0/(256 - v->rate);
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
234 v->channels = 1;
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
235 } /* if */
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
236
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
237 if (!voc_readbytes(src, v, &uc, sizeof (uc)))
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
238 return(0);
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
239
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
240 BAIL_IF_MACRO(uc != 0, "VOC: only supports 8-bit data", 0);
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
241
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
242 v->extended = 0;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
243 v->rest = sblen - 2;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
244 v->size = ST_SIZE_BYTE;
474
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 468
diff changeset
245
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 468
diff changeset
246 bytes_per_second = sample->actual.rate
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 468
diff changeset
247 * sample->actual.channels;
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 468
diff changeset
248 sample->total_time += ( v->rest ) / bytes_per_second * 1000;
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 468
diff changeset
249 sample->total_time += (v->rest % bytes_per_second) * 1000
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 468
diff changeset
250 / bytes_per_second;
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
251 return 1;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
252
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
253 case VOC_DATA_16:
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
254 if (!voc_readbytes(src, v, &new_rate_long, sizeof (Uint32)))
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
255 return 0;
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
256
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
257 new_rate_long = SDL_SwapLE32(new_rate_long);
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
258 BAIL_IF_MACRO(!new_rate_long, "VOC: Sample rate is zero?", 0);
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
259
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
260 if ((v->rate != -1) && (new_rate_long != v->rate))
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
261 BAIL_MACRO("VOC: sample rate codes differ", 0);
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
262
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
263 v->rate = new_rate_long;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
264 sample->actual.rate = new_rate_long;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
265
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
266 if (!voc_readbytes(src, v, &uc, sizeof (uc)))
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
267 return 0;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
268
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
269 switch (uc)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
270 {
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
271 case 8: v->size = ST_SIZE_BYTE; break;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
272 case 16: v->size = ST_SIZE_WORD; break;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
273 default:
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
274 BAIL_MACRO("VOC: unknown data size", 0);
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
275 } /* switch */
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
276
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
277 if (!voc_readbytes(src, v, &v->channels, sizeof (Uint8)))
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
278 return 0;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
279
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
280 if (!voc_readbytes(src, v, trash, sizeof (Uint8) * 6))
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
281 return 0;
474
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 468
diff changeset
282 v->rest = sblen - 12;
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
283
474
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 468
diff changeset
284 bytes_per_second = ((v->size == ST_SIZE_WORD) ? (2) : (1)) *
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 468
diff changeset
285 sample->actual.rate * v->channels;
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 468
diff changeset
286 sample->total_time += v->rest / bytes_per_second * 1000;
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 468
diff changeset
287 sample->total_time += ( v->rest % bytes_per_second ) * 1000
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 468
diff changeset
288 / bytes_per_second;
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
289 return 1;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
290
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
291 case VOC_CONT:
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
292 v->rest = sblen;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
293 return 1;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
294
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
295 case VOC_SILENCE:
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
296 if (!voc_readbytes(src, v, &period, sizeof (period)))
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
297 return 0;
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
298
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
299 period = SDL_SwapLE16(period);
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
300
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
301 if (!voc_readbytes(src, v, &uc, sizeof (uc)))
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
302 return 0;
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
303
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
304 BAIL_IF_MACRO(uc == 0, "VOC: silence sample rate is zero", 0);
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
305
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
306 /*
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
307 * Some silence-packed files have gratuitously
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
308 * different sample rate codes in silence.
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
309 * Adjust period.
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
310 */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
311 if ((v->rate != -1) && (uc != v->rate))
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
312 period = (period * (256 - uc))/(256 - v->rate);
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
313 else
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
314 v->rate = uc;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
315 v->rest = period;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
316 v->silent = 1;
474
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 468
diff changeset
317
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 468
diff changeset
318 sample->total_time += (period) / (v->rate) * 1000;
c66080364dff Most decoders now report total sample play time, now. Technically, this
Ryan C. Gordon <icculus@icculus.org>
parents: 468
diff changeset
319 sample->total_time += (period % v->rate) * 1000 / v->rate;
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
320 return 1;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
321
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
322 case VOC_LOOP:
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
323 case VOC_LOOPEND:
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
324 for(i = 0; i < sblen; i++) /* skip repeat loops. */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
325 {
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
326 if (!voc_readbytes(src, v, trash, sizeof (Uint8)))
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
327 return 0;
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
328 } /* for */
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
329 break;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
330
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
331 case VOC_EXTENDED:
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
332 /* An Extended block is followed by a data block */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
333 /* Set this byte so we know to use the rate */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
334 /* value from the extended block and not the */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
335 /* data block. */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
336 v->extended = 1;
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
337 if (!voc_readbytes(src, v, &new_rate_short, sizeof (Uint16)))
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
338 return 0;
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
339
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
340 new_rate_short = SDL_SwapLE16(new_rate_short);
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
341 BAIL_IF_MACRO(!new_rate_short, "VOC: sample rate is zero", 0);
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
342
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
343 if ((v->rate != -1) && (new_rate_short != v->rate))
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
344 BAIL_MACRO("VOC: sample rate codes differ", 0);
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
345
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
346 v->rate = new_rate_short;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
347
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
348 if (!voc_readbytes(src, v, &uc, sizeof (uc)))
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
349 return 0;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
350
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
351 BAIL_IF_MACRO(uc != 0, "VOC: only supports 8-bit data", 0);
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
352
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
353 if (!voc_readbytes(src, v, &uc, sizeof (uc)))
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
354 return 0;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
355
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
356 if (uc)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
357 sample->actual.channels = 2; /* Stereo */
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
358
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
359 /* Needed number of channels before finishing
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
360 compute for rate */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
361 sample->actual.rate =
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
362 (256000000L/(65536L - v->rate)) / sample->actual.channels;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
363 /* An extended block must be followed by a data */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
364 /* block to be valid so loop back to top so it */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
365 /* can be grabed. */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
366 continue;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
367
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
368 case VOC_MARKER:
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
369 if (!voc_readbytes(src, v, trash, sizeof (Uint8) * 2))
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
370 return 0;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
371
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
372 /* Falling! Falling! */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
373
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
374 default: /* text block or other krapola. */
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
375 for(i = 0; i < sblen; i++) /* skip repeat loops. */
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
376 {
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
377 if (!voc_readbytes(src, v, trash, sizeof (Uint8)))
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
378 return 0;
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
379 } /* for */
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
380
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
381 if (block == VOC_TEXT)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
382 continue; /* get next block */
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
383 } /* switch */
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
384 } /* while */
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
385
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
386 return 1;
335
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
387 } /* voc_get_block */
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
388
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
389
335
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
390 static int voc_read_waveform(Sound_Sample *sample, int fill_buf, Uint32 max)
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
391 {
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
392 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
393 SDL_RWops *src = internal->rw;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
394 vs_t *v = (vs_t *) internal->decoder_private;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
395 int done = 0;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
396 Uint8 silence = 0x80;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
397 Uint8 *buf = internal->buffer;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
398
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
399 if (v->rest == 0)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
400 {
468
cd46c97e58bc Fixed broken VOC decoder...would always dereference NULL during VOC_open().
Ryan C. Gordon <icculus@icculus.org>
parents: 449
diff changeset
401 if (!voc_get_block(sample, v))
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
402 return 0;
335
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
403 } /* if */
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
404
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
405 if (v->rest == 0)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
406 return 0;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
407
335
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
408 max = (v->rest < max) ? v->rest : max;
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
409
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
410 if (v->silent)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
411 {
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
412 if (v->size == ST_SIZE_WORD)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
413 silence = 0x00;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
414
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
415 /* Fill in silence */
335
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
416 if (fill_buf)
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
417 memset(buf + v->bufpos, silence, max);
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
418
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
419 done = max;
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
420 v->rest -= done;
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
421 } /* if */
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
422
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
423 else
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
424 {
335
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
425 if (fill_buf)
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
426 {
335
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
427 done = SDL_RWread(src, buf + v->bufpos, 1, max);
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
428 if (done < max)
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
429 {
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
430 __Sound_SetError("VOC: i/o error");
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
431 sample->flags |= SOUND_SAMPLEFLAG_ERROR;
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
432 } /* if */
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
433 } /* if */
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
434
335
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
435 else
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
436 {
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
437 int cur, rc;
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
438 cur = SDL_RWtell(src);
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
439 if (cur >= 0)
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
440 {
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
441 rc = SDL_RWseek(src, max, SEEK_CUR);
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
442 if (rc >= 0)
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
443 done = rc - cur;
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
444 else
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
445 {
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
446 __Sound_SetError("VOC: seek error");
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
447 sample->flags |= SOUND_SAMPLEFLAG_ERROR;
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
448 } /* else */
335
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
449 } /* if */
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
450 } /* else */
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
451
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
452 v->rest -= done;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
453 v->bufpos += done;
335
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
454 } /* else */
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
455
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
456 return(done);
22
f6e679afe88b Byte ordering fix, changed voc_read to voc_read_waveform, and cleaned up
Ryan C. Gordon <icculus@icculus.org>
parents: 14
diff changeset
457 } /* voc_read_waveform */
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
458
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
459
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
460 static int VOC_open(Sound_Sample *sample, const char *ext)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
461 {
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
462 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
463 vs_t *v = NULL;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
464
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
465 if (!voc_check_header(internal->rw))
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
466 return(0);
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
467
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
468 v = (vs_t *) malloc(sizeof (vs_t));
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
469 BAIL_IF_MACRO(v == NULL, ERR_OUT_OF_MEMORY, 0);
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
470 memset(v, '\0', sizeof (vs_t));
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
471
224
1bafef18dabf Implemented rewind method.
Ryan C. Gordon <icculus@icculus.org>
parents: 221
diff changeset
472 v->start_pos = SDL_RWtell(internal->rw);
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
473 v->rate = -1;
468
cd46c97e58bc Fixed broken VOC decoder...would always dereference NULL during VOC_open().
Ryan C. Gordon <icculus@icculus.org>
parents: 449
diff changeset
474 if (!voc_get_block(sample, v))
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
475 {
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
476 free(v);
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
477 return(0);
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
478 } /* if */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
479
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
480 if (v->rate == -1)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
481 {
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
482 free(v);
387
fb519e6028e3 Changed all the Sound_SetError() calls to __Sound_SetError (or BAIL*_MACRO)
Ryan C. Gordon <icculus@icculus.org>
parents: 385
diff changeset
483 BAIL_MACRO("VOC: data had no sound!", 0);
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
484 } /* if */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
485
62
b13fafb976be Changed _D macro to DBGSND.
Ryan C. Gordon <icculus@icculus.org>
parents: 47
diff changeset
486 SNDDBG(("VOC: Accepting data stream.\n"));
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
487 sample->actual.format = (v->size == ST_SIZE_WORD) ? AUDIO_S16LSB:AUDIO_U8;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
488 sample->actual.channels = v->channels;
335
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
489 sample->flags = SOUND_SAMPLEFLAG_CANSEEK;
449
daeb71a3f1ed Extremely minor cleanup.
Ryan C. Gordon <icculus@icculus.org>
parents: 401
diff changeset
490 internal->decoder_private = v;
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
491 return(1);
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
492 } /* VOC_open */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
493
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
494
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
495 static void VOC_close(Sound_Sample *sample)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
496 {
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
497 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
498 free(internal->decoder_private);
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
499 } /* VOC_close */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
500
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
501
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
502 static Uint32 VOC_read(Sound_Sample *sample)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
503 {
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
504 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
505 vs_t *v = (vs_t *) internal->decoder_private;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
506
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
507 v->bufpos = 0;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
508 while (v->bufpos < internal->buffer_size)
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
509 {
335
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
510 Uint32 rc = voc_read_waveform(sample, 1, internal->buffer_size);
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
511 if (rc == 0)
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
512 {
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
513 sample->flags |= (v->error) ?
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
514 SOUND_SAMPLEFLAG_ERROR :
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
515 SOUND_SAMPLEFLAG_EOF;
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
516 break;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
517 } /* if */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
518
468
cd46c97e58bc Fixed broken VOC decoder...would always dereference NULL during VOC_open().
Ryan C. Gordon <icculus@icculus.org>
parents: 449
diff changeset
519 if (!voc_get_block(sample, v))
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
520 {
385
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
521 sample->flags |= (v->error) ?
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
522 SOUND_SAMPLEFLAG_ERROR :
9efb760c4a6b FIXME removal and cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 377
diff changeset
523 SOUND_SAMPLEFLAG_EOF;
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
524 break;
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
525 } /* if */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
526 } /* while */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
527
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
528 return(v->bufpos);
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
529 } /* VOC_read */
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
530
221
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
531
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
532 static int VOC_rewind(Sound_Sample *sample)
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
533 {
224
1bafef18dabf Implemented rewind method.
Ryan C. Gordon <icculus@icculus.org>
parents: 221
diff changeset
534 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
1bafef18dabf Implemented rewind method.
Ryan C. Gordon <icculus@icculus.org>
parents: 221
diff changeset
535 vs_t *v = (vs_t *) internal->decoder_private;
1bafef18dabf Implemented rewind method.
Ryan C. Gordon <icculus@icculus.org>
parents: 221
diff changeset
536 int rc = SDL_RWseek(internal->rw, v->start_pos, SEEK_SET);
1bafef18dabf Implemented rewind method.
Ryan C. Gordon <icculus@icculus.org>
parents: 221
diff changeset
537 BAIL_IF_MACRO(rc != v->start_pos, ERR_IO_ERROR, 0);
1bafef18dabf Implemented rewind method.
Ryan C. Gordon <icculus@icculus.org>
parents: 221
diff changeset
538 v->rest = 0;
1bafef18dabf Implemented rewind method.
Ryan C. Gordon <icculus@icculus.org>
parents: 221
diff changeset
539 return(1);
221
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
540 } /* VOC_rewind */
c9772a9f5271 Initial implementation or stubs for rewind method. Other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 184
diff changeset
541
306
c97be6e1bd27 Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents: 301
diff changeset
542
c97be6e1bd27 Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents: 301
diff changeset
543 static int VOC_seek(Sound_Sample *sample, Uint32 ms)
c97be6e1bd27 Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents: 301
diff changeset
544 {
335
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
545 /*
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
546 * VOCs don't lend themselves well to seeking, since you have to
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
547 * parse each section, which is an arbitrary size. The best we can do
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
548 * is rewind, set a flag saying not to write the waveforms to a buffer,
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
549 * and decode to the point that we want. Ugh. Fortunately, there's
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
550 * really no such thing as a large VOC, due to the era and hardware that
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
551 * spawned them, so even though this is inefficient, this is still a
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
552 * relatively fast operation in most cases.
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
553 */
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
554
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
555 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
556 vs_t *v = (vs_t *) internal->decoder_private;
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
557 int offset = __Sound_convertMsToBytePos(&sample->actual, ms);
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
558 int origpos = SDL_RWtell(internal->rw);
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
559 int origrest = v->rest;
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
560
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
561 BAIL_IF_MACRO(!VOC_rewind(sample), NULL, 0);
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
562
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
563 v->bufpos = 0;
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
564
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
565 while (offset > 0)
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
566 {
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
567 Uint32 rc = voc_read_waveform(sample, 0, offset);
468
cd46c97e58bc Fixed broken VOC decoder...would always dereference NULL during VOC_open().
Ryan C. Gordon <icculus@icculus.org>
parents: 449
diff changeset
568 if ( (rc == 0) || (!voc_get_block(sample, v)) )
335
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
569 {
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
570 SDL_RWseek(internal->rw, origpos, SEEK_SET);
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
571 v->rest = origrest;
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
572 return(0);
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
573 } /* if */
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
574
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
575 offset -= rc;
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
576 } /* while */
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
577
f6475949cd59 Implemented seek method.
Ryan C. Gordon <icculus@icculus.org>
parents: 306
diff changeset
578 return(1);
306
c97be6e1bd27 Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents: 301
diff changeset
579 } /* VOC_seek */
c97be6e1bd27 Added framework for Sound_Seek() support.
Ryan C. Gordon <icculus@icculus.org>
parents: 301
diff changeset
580
64
40006625142a Changes in preparation of autoconf support.
Ryan C. Gordon <icculus@icculus.org>
parents: 62
diff changeset
581 #endif /* SOUND_SUPPORTS_VOC */
14
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
582
41e5e07c5fed Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
583 /* end of voc.c ... */