annotate decoders/timidity/common.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 9c12dc86d482
children
rev   line source
199
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
1 /*
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
2
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
3 TiMidity -- Experimental MIDI to WAVE converter
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
4 Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
5
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
6 This program is free software; you can redistribute it and/or modify
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
7 it under the terms of the GNU General Public License as published by
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
8 the Free Software Foundation; either version 2 of the License, or
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
9 (at your option) any later version.
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
10
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
11 This program is distributed in the hope that it will be useful,
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
14 GNU General Public License for more details.
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
15
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
17 along with this program; if not, write to the Free Software
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
19
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
20 common.c
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
21
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
22 */
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
23
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
24 #if HAVE_CONFIG_H
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
25 # include <config.h>
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
26 #endif
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
27
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
28 #include <stdio.h>
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
29 #include <stdlib.h>
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
30 #include <string.h>
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
31
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
32 #include "SDL_sound.h"
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
33
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
34 #define __SDL_SOUND_INTERNAL__
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
35 #include "SDL_sound_internal.h"
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
36
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
37 #include "options.h"
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
38 #include "common.h"
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
39
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
40 /* The paths in this list will be tried whenever we're reading a file */
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
41 static PathList *pathlist = NULL; /* This is a linked list */
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
42
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
43 /* This is meant to find and open files for reading */
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
44 SDL_RWops *open_file(char *name)
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
45 {
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
46 SDL_RWops *rw;
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
47
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
48 if (!name || !(*name))
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
49 {
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
50 SNDDBG(("Attempted to open nameless file.\n"));
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
51 return 0;
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
52 }
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
53
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
54 /* First try the given name */
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
55
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
56 SNDDBG(("Trying to open %s\n", name));
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
57 if ((rw = SDL_RWFromFile(name, "rb")))
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
58 return rw;
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
59
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
60 if (name[0] != PATH_SEP)
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
61 {
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
62 char current_filename[1024];
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
63 PathList *plp = pathlist;
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
64 int l;
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
65
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
66 while (plp) /* Try along the path then */
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
67 {
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
68 *current_filename = 0;
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
69 l = strlen(plp->path);
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
70 if(l)
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
71 {
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
72 strcpy(current_filename, plp->path);
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
73 if(current_filename[l - 1] != PATH_SEP)
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
74 {
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
75 current_filename[l] = PATH_SEP;
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
76 current_filename[l + 1] = '\0';
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
77 }
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
78 }
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
79 strcat(current_filename, name);
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
80 SNDDBG(("Trying to open %s\n", current_filename));
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
81 if ((rw = SDL_RWFromFile(current_filename, "rb")))
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
82 return rw;
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
83 plp = plp->next;
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
84 }
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
85 }
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
86
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
87 /* Nothing could be opened. */
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
88 SNDDBG(("Could not open %s\n", name));
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
89 return 0;
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
90 }
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
91
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
92 /* This'll allocate memory or die. */
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
93 void *safe_malloc(size_t count)
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
94 {
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
95 void *p;
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
96
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
97 p = malloc(count);
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
98 if (p == NULL)
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
99 SNDDBG(("Sorry. Couldn't malloc %d bytes.\n", count));
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
100
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
101 return p;
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
102 }
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
103
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
104 /* This adds a directory to the path list */
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
105 void add_to_pathlist(char *s)
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
106 {
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
107 PathList *plp = safe_malloc(sizeof(PathList));
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
108
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
109 if (plp == NULL)
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
110 return;
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
111
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
112 plp->path = safe_malloc(strlen(s) + 1);
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
113 if (plp->path == NULL)
408
3da217bd0e48 Memory leak fixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 199
diff changeset
114 {
3da217bd0e48 Memory leak fixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 199
diff changeset
115 free(plp);
199
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
116 return;
408
3da217bd0e48 Memory leak fixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 199
diff changeset
117 }
3da217bd0e48 Memory leak fixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 199
diff changeset
118
199
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
119 strcpy(plp->path, s);
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
120 plp->next = pathlist;
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
121 pathlist = plp;
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
122 }
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
123
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
124 void free_pathlist(void)
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
125 {
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
126 PathList *plp = pathlist;
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
127 PathList *next;
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
128
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
129 while (plp)
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
130 {
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
131 next = plp->next;
408
3da217bd0e48 Memory leak fixes.
Ryan C. Gordon <icculus@icculus.org>
parents: 199
diff changeset
132 free(plp->path);
199
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
133 free(plp);
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
134 plp = next;
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
135 }
457
9c12dc86d482 Fixed typo in CHANGELOG
hercules
parents: 408
diff changeset
136 pathlist = NULL;
199
2d887640d300 Initial add.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
137 }