annotate extra_rwops.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 47cc2de2ae36
children 137c0b00ea4c 50bb9a6cebfe
rev   line source
8
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
1 /*
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
2 * SDL_sound -- An abstract sound format decoding API.
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
3 * Copyright (C) 2001 Ryan C. Gordon.
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
4 *
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
dca15bb29d35 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.
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
9 *
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
13 * Lesser General Public License for more details.
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
14 *
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
18 */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
19
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
20 /*
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
21 * Some extra RWops that are needed or are just handy to have.
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
22 *
184
47cc2de2ae36 Changed reference to "LICENSE" file to "COPYING".
Ryan C. Gordon <icculus@icculus.org>
parents: 83
diff changeset
23 * Please see the file COPYING in the source's root directory.
8
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
24 *
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
25 * This file written by Ryan C. Gordon. (icculus@clutteredmind.org)
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
26 */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
27
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
28 #include <stdio.h>
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
29 #include <stdlib.h>
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
30 #include "SDL.h"
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
31
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
32
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
33 /*
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
34 * The Reference Counter RWops...
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
35 */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
36
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
37
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
38 typedef struct
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
39 {
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
40 SDL_RWops *rw; /* The actual RWops we're refcounting... */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
41 int refcount; /* The refcount; starts at 1. If goes to 0, delete. */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
42 } RWRefCounterData;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
43
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
44
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
45 /* Just pass through to the actual SDL_RWops's method... */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
46 static int refcounter_seek(SDL_RWops *rw, int offset, int whence)
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
47 {
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
48 RWRefCounterData *data = (RWRefCounterData *) rw->hidden.unknown.data1;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
49 return(data->rw->seek(data->rw, offset, whence));
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
50 } /* refcounter_seek */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
51
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
52
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
53 /* Just pass through to the actual SDL_RWops's method... */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
54 static int refcounter_read(SDL_RWops *rw, void *ptr, int size, int maxnum)
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
55 {
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
56 RWRefCounterData *data = (RWRefCounterData *) rw->hidden.unknown.data1;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
57 return(data->rw->read(data->rw, ptr, size, maxnum));
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
58 } /* refcounter_read */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
59
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
60
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
61 /* Just pass through to the actual SDL_RWops's method... */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
62 static int refcounter_write(SDL_RWops *rw, const void *ptr, int size, int num)
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
63 {
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
64 RWRefCounterData *data = (RWRefCounterData *) rw->hidden.unknown.data1;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
65 return(data->rw->write(data->rw, ptr, size, num));
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
66 } /* refcounter_write */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
67
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
68
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
69 /*
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
70 * Decrement the reference count. If there are no more references, pass
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
71 * through to the actual SDL_RWops's method, and then clean ourselves up.
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
72 */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
73 static int refcounter_close(SDL_RWops *rw)
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
74 {
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
75 int retval = 0;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
76 RWRefCounterData *data = (RWRefCounterData *) rw->hidden.unknown.data1;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
77 data->refcount--;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
78 if (data->refcount <= 0)
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
79 {
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
80 retval = data->rw->close(data->rw);
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
81 free(data);
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
82 SDL_FreeRW(rw);
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
83 } /* if */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
84
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
85 return(retval);
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
86 } /* refcounter_close */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
87
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
88
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
89 void RWops_RWRefCounter_addRef(SDL_RWops *rw)
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
90 {
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
91 RWRefCounterData *data = (RWRefCounterData *) rw->hidden.unknown.data1;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
92 data->refcount++;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
93 } /* RWops_RWRefCounter_addRef */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
94
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
95
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
96 SDL_RWops *RWops_RWRefCounter_new(SDL_RWops *rw)
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
97 {
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
98 SDL_RWops *retval = NULL;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
99
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
100 if (rw == NULL)
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
101 {
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
102 SDL_SetError("NULL argument to RWops_RWRefCounter_new().");
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
103 return(NULL);
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
104 } /* if */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
105
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
106 retval = SDL_AllocRW();
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
107 if (retval != NULL)
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
108 {
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
109 RWRefCounterData *data;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
110 data = (RWRefCounterData *) malloc(sizeof (RWRefCounterData));
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
111 if (data == NULL)
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
112 {
83
2b5ba7f33840 Stopped using SDL_OutOfMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 8
diff changeset
113 SDL_SetError("Out of memory.");
8
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
114 SDL_FreeRW(retval);
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
115 retval = NULL;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
116 } /* if */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
117 else
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
118 {
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
119 data->rw = rw;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
120 data->refcount = 1;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
121 retval->hidden.unknown.data1 = data;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
122 retval->seek = refcounter_seek;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
123 retval->read = refcounter_read;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
124 retval->write = refcounter_write;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
125 retval->close = refcounter_close;
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
126 } /* else */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
127 } /* if */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
128
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
129 return(retval);
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
130 } /* RWops_RWRefCounter_new */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
131
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
132
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
133 /* end of extra_rwops.c ... */
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
134
dca15bb29d35 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
135