Mercurial > SDL_sound_CoreAudio
annotate playsound/physfsrwops.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 | d8c0315deba9 |
children | 35dfa9d9782e |
rev | line source |
---|---|
286 | 1 /* |
2 * This code provides a glue layer between PhysicsFS and Simple Directmedia | |
3 * Layer's (SDL) RWops i/o abstraction. | |
4 * | |
5 * License: this code is public domain. I make no warranty that it is useful, | |
6 * correct, harmless, or environmentally safe. | |
7 * | |
8 * This particular file may be used however you like, including copying it | |
9 * verbatim into a closed-source project, exploiting it commercially, and | |
10 * removing any trace of my name from the source (although I hope you won't | |
11 * do that). I welcome enhancements and corrections to this file, but I do | |
12 * not require you to send me patches if you make changes. | |
13 * | |
14 * Unless otherwise stated, the rest of PhysicsFS falls under the GNU Lesser | |
15 * General Public License: http://www.gnu.org/licenses/lgpl.txt | |
16 * | |
17 * SDL falls under the LGPL, too. You can get SDL at http://www.libsdl.org/ | |
18 * | |
19 * This file was written by Ryan C. Gordon. (icculus@clutteredmind.org). | |
20 */ | |
21 | |
22 #include <stdio.h> /* used for SEEK_SET, SEEK_CUR, SEEK_END ... */ | |
23 #include "physfsrwops.h" | |
24 | |
25 static int physfsrwops_seek(SDL_RWops *rw, int offset, int whence) | |
26 { | |
27 PHYSFS_file *handle = (PHYSFS_file *) rw->hidden.unknown.data1; | |
28 int pos = 0; | |
29 | |
30 if (whence == SEEK_SET) | |
31 { | |
32 pos = offset; | |
33 } /* if */ | |
34 | |
35 else if (whence == SEEK_CUR) | |
36 { | |
296
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
37 PHYSFS_sint64 current = PHYSFS_tell(handle); |
286 | 38 if (current == -1) |
39 { | |
40 SDL_SetError("Can't find position in file: %s", | |
41 PHYSFS_getLastError()); | |
42 return(-1); | |
43 } /* if */ | |
44 | |
296
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
45 pos = (int) current; |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
46 if ( ((PHYSFS_sint64) pos) != current ) |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
47 { |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
48 SDL_SetError("Can't fit current file position in an int!"); |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
49 return(-1); |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
50 } /* if */ |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
51 |
286 | 52 if (offset == 0) /* this is a "tell" call. We're done. */ |
296
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
53 return(pos); |
286 | 54 |
296
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
55 pos += offset; |
286 | 56 } /* else if */ |
57 | |
58 else if (whence == SEEK_END) | |
59 { | |
296
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
60 PHYSFS_sint64 len = PHYSFS_fileLength(handle); |
286 | 61 if (len == -1) |
62 { | |
63 SDL_SetError("Can't find end of file: %s", PHYSFS_getLastError()); | |
64 return(-1); | |
65 } /* if */ | |
66 | |
296
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
67 pos = (int) len; |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
68 if ( ((PHYSFS_sint64) pos) != len ) |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
69 { |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
70 SDL_SetError("Can't fit end-of-file position in an int!"); |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
71 return(-1); |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
72 } /* if */ |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
73 |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
74 pos += offset; |
286 | 75 } /* else if */ |
76 | |
77 else | |
78 { | |
79 SDL_SetError("Invalid 'whence' parameter."); | |
80 return(-1); | |
81 } /* else */ | |
82 | |
296
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
83 if ( pos < 0 ) |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
84 { |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
85 SDL_SetError("Attempt to seek past start of file."); |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
86 return(-1); |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
87 } /* if */ |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
88 |
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
89 if (!PHYSFS_seek(handle, (PHYSFS_uint64) pos)) |
286 | 90 { |
91 SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError()); | |
92 return(-1); | |
93 } /* if */ | |
94 | |
95 return(pos); | |
96 } /* physfsrwops_seek */ | |
97 | |
98 | |
99 static int physfsrwops_read(SDL_RWops *rw, void *ptr, int size, int maxnum) | |
100 { | |
101 PHYSFS_file *handle = (PHYSFS_file *) rw->hidden.unknown.data1; | |
296
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
102 PHYSFS_sint64 rc = PHYSFS_read(handle, ptr, size, maxnum); |
286 | 103 if (rc != maxnum) |
104 { | |
105 if (!PHYSFS_eof(handle)) /* not EOF? Must be an error. */ | |
106 SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError()); | |
107 } /* if */ | |
108 | |
296
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
109 return((int) rc); |
286 | 110 } /* physfsrwops_read */ |
111 | |
112 | |
113 static int physfsrwops_write(SDL_RWops *rw, const void *ptr, int size, int num) | |
114 { | |
115 PHYSFS_file *handle = (PHYSFS_file *) rw->hidden.unknown.data1; | |
296
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
116 PHYSFS_sint64 rc = PHYSFS_write(handle, ptr, size, num); |
286 | 117 if (rc != num) |
118 SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError()); | |
119 | |
296
d8c0315deba9
Updated to fix bugs and deal with API breakage in PhysicsFS.
Ryan C. Gordon <icculus@icculus.org>
parents:
286
diff
changeset
|
120 return((int) rc); |
286 | 121 } /* physfsrwops_write */ |
122 | |
123 | |
124 static int physfsrwops_close(SDL_RWops *rw) | |
125 { | |
126 PHYSFS_file *handle = (PHYSFS_file *) rw->hidden.unknown.data1; | |
127 if (!PHYSFS_close(handle)) | |
128 { | |
129 SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError()); | |
130 return(-1); | |
131 } /* if */ | |
132 | |
133 SDL_FreeRW(rw); | |
134 return(0); | |
135 } /* physfsrwops_close */ | |
136 | |
137 | |
138 static SDL_RWops *create_rwops(PHYSFS_file *handle) | |
139 { | |
140 SDL_RWops *retval = NULL; | |
141 | |
142 if (handle == NULL) | |
143 SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError()); | |
144 else | |
145 { | |
146 retval = SDL_AllocRW(); | |
147 if (retval != NULL) | |
148 { | |
149 retval->seek = physfsrwops_seek; | |
150 retval->read = physfsrwops_read; | |
151 retval->write = physfsrwops_write; | |
152 retval->close = physfsrwops_close; | |
153 retval->hidden.unknown.data1 = handle; | |
154 } /* if */ | |
155 } /* else */ | |
156 | |
157 return(retval); | |
158 } /* create_rwops */ | |
159 | |
160 | |
161 SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_file *handle) | |
162 { | |
163 SDL_RWops *retval = NULL; | |
164 if (handle == NULL) | |
165 SDL_SetError("NULL pointer passed to PHYSFSRWOPS_makeRWops()."); | |
166 else | |
167 retval = create_rwops(handle); | |
168 | |
169 return(retval); | |
170 } /* PHYSFSRWOPS_makeRWops */ | |
171 | |
172 | |
173 SDL_RWops *PHYSFSRWOPS_openRead(const char *fname) | |
174 { | |
175 return(create_rwops(PHYSFS_openRead(fname))); | |
176 } /* PHYSFSRWOPS_openRead */ | |
177 | |
178 | |
179 SDL_RWops *PHYSFSRWOPS_openWrite(const char *fname) | |
180 { | |
181 return(create_rwops(PHYSFS_openWrite(fname))); | |
182 } /* PHYSFSRWOPS_openWrite */ | |
183 | |
184 | |
185 SDL_RWops *PHYSFSRWOPS_openAppend(const char *fname) | |
186 { | |
187 return(create_rwops(PHYSFS_openAppend(fname))); | |
188 } /* PHYSFSRWOPS_openAppend */ | |
189 | |
190 | |
191 /* end of physfsrwops.c ... */ | |
192 |