1305
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1 /* shn.c - main functions for xmms-shn
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
2 * Copyright (C) 2000-2007 Jason Jordan <shnutils@freeshell.org>
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
3 *
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
4 * This program is free software; you can redistribute it and/or modify
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
5 * it under the terms of the GNU General Public License as published by
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
6 * the Free Software Foundation; either version 2 of the License, or
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
7 * (at your option) any later version.
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
8 *
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
9 * This program is distributed in the hope that it will be useful,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
12 * GNU General Public License for more details.
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
13 *
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
14 * You should have received a copy of the GNU General Public License
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
15 * along with this program; if not, write to the Free Software
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
17 */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
18
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
19 /*
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
20 * $Id: shn.c,v 1.38 2007/03/23 05:49:48 jason Exp $
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
21 */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
22
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
23 #include <stdio.h>
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
24 #include <stdlib.h>
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
25 #include <math.h>
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
26 #include <glib.h>
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
27 #include <audacious/util.h>
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
28 #include <audacious/configdb.h>
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
29 #include "shorten.h"
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
30
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
31 #ifdef HAVE_CONFIG_H
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
32 #include "config.h"
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
33 #endif
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
34
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
35 static void shn_about(void);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
36 static void shn_configure(void);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
37 static void shn_init(void);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
38 static int shn_is_our_fd(char *, VFSFile *fd);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
39 static void shn_play(InputPlayback *);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
40 static void shn_stop(InputPlayback *);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
41 static void shn_seek(InputPlayback *, int);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
42 static void shn_pause(InputPlayback *, short);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
43 static void shn_get_file_info(char *,char **,int *);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
44 static void shn_display_file_info(char *);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
45
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
46 gchar *shn_fmts[] = { "shn", NULL };
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
47
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
48 InputPlugin shn_ip =
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
49 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
50 NULL,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
51 NULL,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
52 "SHN Player " VERSION,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
53 shn_init,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
54 shn_about,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
55 shn_configure,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
56 NULL,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
57 NULL,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
58 shn_play,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
59 shn_stop,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
60 shn_pause,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
61 shn_seek,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
62 NULL,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
63 NULL,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
64 NULL,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
65 NULL,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
66 NULL,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
67 NULL,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
68 NULL,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
69 NULL,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
70 NULL,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
71 shn_get_file_info,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
72 shn_display_file_info,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
73 NULL,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
74 NULL,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
75 NULL,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
76 NULL,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
77 shn_is_our_fd,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
78 shn_fmts,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
79 };
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
80
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
81 InputPlugin *shn_iplist[] = { &shn_ip, NULL };
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
82
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
83 DECLARE_PLUGIN(shnplug, NULL, NULL, shn_iplist, NULL, NULL, NULL, NULL);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
84
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
85 shn_file *shnfile;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
86 shn_config shn_cfg;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
87
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
88 static pthread_t decode_thread;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
89 static gboolean audio_error = FALSE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
90
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
91 static void shn_init()
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
92 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
93 ConfigDb *cfg;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
94
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
95 shn_cfg.error_output_method = ERROR_OUTPUT_DEVNULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
96 shn_cfg.error_output_method_config_name = "error_output_method";
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
97 shn_cfg.seek_tables_path = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
98 shn_cfg.seek_tables_path_config_name = "seek_tables_path";
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
99 shn_cfg.relative_seek_tables_path = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
100 shn_cfg.relative_seek_tables_path_config_name = "relative_seek_tables_path";
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
101 shn_cfg.verbose = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
102 shn_cfg.verbose_config_name = "verbose";
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
103 shn_cfg.swap_bytes = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
104 shn_cfg.swap_bytes_config_name = "swap_bytes";
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
105 shn_cfg.load_textfiles = FALSE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
106 shn_cfg.load_textfiles_config_name = "load_textfiles";
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
107 shn_cfg.textfile_extensions = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
108 shn_cfg.textfile_extensions_config_name = "textfile_extensions";
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
109
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
110 if ((cfg = bmp_cfg_db_open()) != 0)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
111 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
112 bmp_cfg_db_get_int(cfg, XMMS_SHN_VERSION_TAG, shn_cfg.error_output_method_config_name, &shn_cfg.error_output_method);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
113 bmp_cfg_db_get_bool(cfg, XMMS_SHN_VERSION_TAG, shn_cfg.verbose_config_name, &shn_cfg.verbose);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
114 if (!bmp_cfg_db_get_string(cfg, XMMS_SHN_VERSION_TAG, shn_cfg.seek_tables_path_config_name, &shn_cfg.seek_tables_path))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
115 shn_cfg.seek_tables_path = g_strdup(g_get_home_dir());
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
116 if (!bmp_cfg_db_get_string(cfg, XMMS_SHN_VERSION_TAG, shn_cfg.relative_seek_tables_path_config_name, &shn_cfg.relative_seek_tables_path))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
117 shn_cfg.relative_seek_tables_path = g_strdup("");
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
118 bmp_cfg_db_get_bool(cfg, XMMS_SHN_VERSION_TAG, shn_cfg.swap_bytes_config_name, &shn_cfg.swap_bytes);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
119 bmp_cfg_db_get_bool(cfg, XMMS_SHN_VERSION_TAG, shn_cfg.load_textfiles_config_name, &shn_cfg.load_textfiles);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
120 if (!bmp_cfg_db_get_string(cfg, XMMS_SHN_VERSION_TAG, shn_cfg.textfile_extensions_config_name, &shn_cfg.textfile_extensions))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
121 shn_cfg.textfile_extensions = g_strdup("txt,nfo");
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
122 bmp_cfg_db_close(cfg);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
123 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
124 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
125
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
126 static void shn_about()
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
127 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
128 shn_display_about();
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
129 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
130
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
131 static void shn_configure()
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
132 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
133 shn_display_configure();
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
134 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
135
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
136 int init_decode_state(shn_file *this_shn)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
137 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
138 if (this_shn->decode_state)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
139 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
140 if (this_shn->decode_state->getbuf)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
141 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
142 free(this_shn->decode_state->getbuf);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
143 this_shn->decode_state->getbuf = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
144 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
145
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
146 if (this_shn->decode_state->writebuf)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
147 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
148 free(this_shn->decode_state->writebuf);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
149 this_shn->decode_state->writebuf = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
150 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
151
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
152 if (this_shn->decode_state->writefub)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
153 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
154 free(this_shn->decode_state->writefub);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
155 this_shn->decode_state->writefub = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
156 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
157
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
158 free(this_shn->decode_state);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
159 this_shn->decode_state = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
160 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
161
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
162 if (!(this_shn->decode_state = malloc(sizeof(shn_decode_state))))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
163 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
164 shn_debug("Could not allocate memory for decode state data structure");
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
165 return 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
166 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
167
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
168 this_shn->decode_state->getbuf = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
169 this_shn->decode_state->getbufp = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
170 this_shn->decode_state->nbitget = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
171 this_shn->decode_state->nbyteget = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
172 this_shn->decode_state->gbuffer = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
173 this_shn->decode_state->writebuf = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
174 this_shn->decode_state->writefub = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
175 this_shn->decode_state->nwritebuf = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
176
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
177 this_shn->vars.bytes_in_buf = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
178
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
179 return 1;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
180 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
181
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
182 int get_wave_header(shn_file *this_shn)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
183 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
184 slong **buffer = NULL, **offset = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
185 slong lpcqoffset = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
186 int version = FORMAT_VERSION, bitshift = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
187 int ftype = TYPE_EOF;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
188 char *magic = MAGIC;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
189 int blocksize = DEFAULT_BLOCK_SIZE, nchan = DEFAULT_NCHAN;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
190 int i, chan, nwrap, nskip = DEFAULT_NSKIP;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
191 int *qlpc = NULL, maxnlpc = DEFAULT_MAXNLPC, nmean = UNDEFINED_UINT;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
192 int cmd;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
193 int internal_ftype;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
194 int cklen;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
195 int retval = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
196
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
197 if (!init_decode_state(this_shn))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
198 return 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
199
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
200 /***********************/
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
201 /* EXTRACT starts here */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
202 /***********************/
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
203
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
204 /* read magic number */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
205 #ifdef STRICT_FORMAT_COMPATABILITY
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
206 if(FORMAT_VERSION < 2)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
207 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
208 for(i = 0; i < strlen(magic); i++) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
209 if(getc_exit(this_shn->vars.fd) != magic[i])
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
210 return 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
211 this_shn->vars.bytes_read++;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
212 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
213
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
214 /* get version number */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
215 version = getc_exit(this_shn->vars.fd);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
216 this_shn->vars.bytes_read++;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
217 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
218 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
219 #endif /* STRICT_FORMAT_COMPATABILITY */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
220 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
221 int nscan = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
222
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
223 version = MAX_VERSION + 1;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
224 while(version > MAX_VERSION)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
225 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
226 int byte = vfs_getc(this_shn->vars.fd);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
227 this_shn->vars.bytes_read++;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
228 if(byte == EOF)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
229 return 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
230 if(magic[nscan] != '\0' && byte == magic[nscan])
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
231 nscan++;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
232 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
233 if(magic[nscan] == '\0' && byte <= MAX_VERSION)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
234 version = byte;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
235 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
236 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
237 if(byte == magic[0])
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
238 nscan = 1;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
239 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
240 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
241 nscan = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
242 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
243 version = MAX_VERSION + 1;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
244 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
245 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
246 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
247
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
248 /* check version number */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
249 if(version > MAX_SUPPORTED_VERSION)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
250 return 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
251
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
252 /* set up the default nmean, ignoring the command line state */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
253 nmean = (version < 2) ? DEFAULT_V0NMEAN : DEFAULT_V2NMEAN;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
254
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
255 /* initialise the variable length file read for the compressed stream */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
256 var_get_init(this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
257 if (this_shn->vars.fatal_error)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
258 return 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
259
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
260 /* initialise the fixed length file write for the uncompressed stream */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
261 fwrite_type_init(this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
262
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
263 /* get the internal file type */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
264 internal_ftype = UINT_GET(TYPESIZE, this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
265
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
266 /* has the user requested a change in file type? */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
267 if(internal_ftype != ftype) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
268 if(ftype == TYPE_EOF) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
269 ftype = internal_ftype; /* no problems here */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
270 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
271 else { /* check that the requested conversion is valid */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
272 if(internal_ftype == TYPE_AU1 || internal_ftype == TYPE_AU2 ||
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
273 internal_ftype == TYPE_AU3 || ftype == TYPE_AU1 ||ftype == TYPE_AU2 || ftype == TYPE_AU3)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
274 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
275 retval = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
276 goto got_enough_data;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
277 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
278 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
279 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
280
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
281 nchan = UINT_GET(CHANSIZE, this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
282 this_shn->vars.actual_nchan = nchan;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
283
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
284 /* get blocksize if version > 0 */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
285 if(version > 0)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
286 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
287 int byte;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
288 blocksize = UINT_GET((int) (log((double) DEFAULT_BLOCK_SIZE) / M_LN2),this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
289 maxnlpc = UINT_GET(LPCQSIZE, this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
290 this_shn->vars.actual_maxnlpc = maxnlpc;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
291 nmean = UINT_GET(0, this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
292 this_shn->vars.actual_nmean = nmean;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
293 nskip = UINT_GET(NSKIPSIZE, this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
294 for(i = 0; i < nskip; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
295 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
296 byte = uvar_get(XBYTESIZE,this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
297 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
298 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
299 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
300 blocksize = DEFAULT_BLOCK_SIZE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
301
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
302 nwrap = MAX(NWRAP, maxnlpc);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
303
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
304 /* grab some space for the input buffer */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
305 buffer = long2d((ulong) nchan, (ulong) (blocksize + nwrap),this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
306 if (this_shn->vars.fatal_error)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
307 return 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
308 offset = long2d((ulong) nchan, (ulong) MAX(1, nmean),this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
309 if (this_shn->vars.fatal_error) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
310 if (buffer) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
311 free(buffer);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
312 buffer = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
313 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
314 return 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
315 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
316
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
317 for(chan = 0; chan < nchan; chan++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
318 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
319 for(i = 0; i < nwrap; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
320 buffer[chan][i] = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
321 buffer[chan] += nwrap;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
322 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
323
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
324 if(maxnlpc > 0) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
325 qlpc = (int*) pmalloc((ulong) (maxnlpc * sizeof(*qlpc)),this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
326 if (this_shn->vars.fatal_error) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
327 if (buffer) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
328 free(buffer);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
329 buffer = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
330 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
331 if (offset) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
332 free(offset);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
333 buffer = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
334 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
335 return 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
336 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
337 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
338
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
339 if(version > 1)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
340 lpcqoffset = V2LPCQOFFSET;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
341
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
342 init_offset(offset, nchan, MAX(1, nmean), internal_ftype);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
343
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
344 /* get commands from file and execute them */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
345 chan = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
346 while(1)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
347 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
348 this_shn->vars.reading_function_code = 1;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
349 cmd = uvar_get(FNSIZE,this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
350 this_shn->vars.reading_function_code = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
351
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
352 switch(cmd)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
353 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
354 case FN_ZERO:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
355 case FN_DIFF0:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
356 case FN_DIFF1:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
357 case FN_DIFF2:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
358 case FN_DIFF3:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
359 case FN_QLPC:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
360 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
361 slong coffset, *cbuffer = buffer[chan];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
362 int resn = 0, nlpc, j;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
363
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
364 if(cmd != FN_ZERO)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
365 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
366 resn = uvar_get(ENERGYSIZE,this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
367 if (this_shn->vars.fatal_error) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
368 retval = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
369 goto got_enough_data;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
370 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
371 /* this is a hack as version 0 differed in definition of var_get */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
372 if(version == 0)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
373 resn--;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
374 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
375
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
376 /* find mean offset : N.B. this code duplicated */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
377 if(nmean == 0)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
378 coffset = offset[chan][0];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
379 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
380 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
381 slong sum = (version < 2) ? 0 : nmean / 2;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
382 for(i = 0; i < nmean; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
383 sum += offset[chan][i];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
384 if(version < 2)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
385 coffset = sum / nmean;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
386 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
387 coffset = ROUNDEDSHIFTDOWN(sum / nmean, bitshift);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
388 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
389
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
390 switch(cmd)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
391 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
392 case FN_ZERO:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
393 for(i = 0; i < blocksize; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
394 cbuffer[i] = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
395 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
396 case FN_DIFF0:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
397 for(i = 0; i < blocksize; i++) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
398 cbuffer[i] = var_get(resn,this_shn) + coffset;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
399 if (this_shn->vars.fatal_error) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
400 retval = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
401 goto got_enough_data;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
402 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
403 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
404 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
405 case FN_DIFF1:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
406 for(i = 0; i < blocksize; i++) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
407 cbuffer[i] = var_get(resn,this_shn) + cbuffer[i - 1];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
408 if (this_shn->vars.fatal_error) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
409 retval = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
410 goto got_enough_data;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
411 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
412 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
413 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
414 case FN_DIFF2:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
415 for(i = 0; i < blocksize; i++) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
416 cbuffer[i] = var_get(resn,this_shn) + (2 * cbuffer[i - 1] - cbuffer[i - 2]);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
417 if (this_shn->vars.fatal_error) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
418 retval = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
419 goto got_enough_data;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
420 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
421 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
422 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
423 case FN_DIFF3:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
424 for(i = 0; i < blocksize; i++) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
425 cbuffer[i] = var_get(resn,this_shn) + 3 * (cbuffer[i - 1] - cbuffer[i - 2]) + cbuffer[i - 3];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
426 if (this_shn->vars.fatal_error) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
427 retval = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
428 goto got_enough_data;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
429 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
430 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
431 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
432 case FN_QLPC:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
433 nlpc = uvar_get(LPCQSIZE,this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
434 if (this_shn->vars.fatal_error) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
435 retval = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
436 goto got_enough_data;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
437 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
438
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
439 for(i = 0; i < nlpc; i++) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
440 qlpc[i] = var_get(LPCQUANT,this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
441 if (this_shn->vars.fatal_error) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
442 retval = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
443 goto got_enough_data;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
444 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
445 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
446 for(i = 0; i < nlpc; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
447 cbuffer[i - nlpc] -= coffset;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
448 for(i = 0; i < blocksize; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
449 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
450 slong sum = lpcqoffset;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
451
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
452 for(j = 0; j < nlpc; j++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
453 sum += qlpc[j] * cbuffer[i - j - 1];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
454 cbuffer[i] = var_get(resn,this_shn) + (sum >> LPCQUANT);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
455 if (this_shn->vars.fatal_error) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
456 retval = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
457 goto got_enough_data;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
458 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
459 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
460 if(coffset != 0)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
461 for(i = 0; i < blocksize; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
462 cbuffer[i] += coffset;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
463 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
464 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
465
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
466 /* store mean value if appropriate : N.B. Duplicated code */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
467 if(nmean > 0)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
468 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
469 slong sum = (version < 2) ? 0 : blocksize / 2;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
470
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
471 for(i = 0; i < blocksize; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
472 sum += cbuffer[i];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
473
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
474 for(i = 1; i < nmean; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
475 offset[chan][i - 1] = offset[chan][i];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
476 if(version < 2)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
477 offset[chan][nmean - 1] = sum / blocksize;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
478 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
479 offset[chan][nmean - 1] = (sum / blocksize) << bitshift;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
480 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
481
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
482 if (0 == chan) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
483 this_shn->vars.initial_file_position = this_shn->vars.last_file_position_no_really;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
484 goto got_enough_data;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
485 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
486
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
487 /* do the wrap */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
488 for(i = -nwrap; i < 0; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
489 cbuffer[i] = cbuffer[i + blocksize];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
490
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
491 fix_bitshift(cbuffer, blocksize, bitshift, internal_ftype);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
492
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
493 if(chan == nchan - 1)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
494 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
495 fwrite_type(buffer, ftype, nchan, blocksize, this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
496 this_shn->vars.bytes_in_buf = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
497 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
498
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
499 chan = (chan + 1) % nchan;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
500 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
501 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
502 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
503
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
504 case FN_BLOCKSIZE:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
505 UINT_GET((int) (log((double) blocksize) / M_LN2), this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
506 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
507
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
508 case FN_VERBATIM:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
509 cklen = uvar_get(VERBATIM_CKSIZE_SIZE,this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
510
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
511 while (cklen--) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
512 if (this_shn->vars.bytes_in_header >= OUT_BUFFER_SIZE) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
513 shn_debug("Unexpectedly large header - " PACKAGE " can only handle a maximum of %d bytes",OUT_BUFFER_SIZE);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
514 goto got_enough_data;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
515 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
516 this_shn->vars.bytes_in_buf = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
517 this_shn->vars.header[this_shn->vars.bytes_in_header++] = (char)uvar_get(VERBATIM_BYTE_SIZE,this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
518 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
519 retval = 1;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
520 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
521
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
522 case FN_BITSHIFT:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
523 bitshift = uvar_get(BITSHIFTSIZE,this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
524 this_shn->vars.actual_bitshift = bitshift;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
525 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
526
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
527 default:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
528 goto got_enough_data;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
529 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
530 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
531
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
532 got_enough_data:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
533
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
534 /* wind up */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
535 var_get_quit(this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
536 fwrite_type_quit(this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
537
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
538 if (buffer) free((void *) buffer);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
539 if (offset) free((void *) offset);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
540 if(maxnlpc > 0 && qlpc)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
541 free((void *) qlpc);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
542
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
543 this_shn->vars.bytes_in_buf = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
544
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
545 return retval;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
546 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
547
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
548 void shn_unload(shn_file *this_shn)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
549 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
550 int this_shn_is_shnfile = (this_shn == shnfile) ? 1 : 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
551
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
552 if (this_shn)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
553 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
554 if (this_shn->vars.fd)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
555 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
556 vfs_fclose(this_shn->vars.fd);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
557 this_shn->vars.fd = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
558 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
559
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
560 if (this_shn->decode_state)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
561 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
562 if (this_shn->decode_state->getbuf)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
563 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
564 free(this_shn->decode_state->getbuf);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
565 this_shn->decode_state->getbuf = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
566 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
567
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
568 if (this_shn->decode_state->writebuf)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
569 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
570 free(this_shn->decode_state->writebuf);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
571 this_shn->decode_state->writebuf = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
572 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
573
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
574 if (this_shn->decode_state->writefub)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
575 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
576 free(this_shn->decode_state->writefub);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
577 this_shn->decode_state->writefub = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
578 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
579
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
580 free(this_shn->decode_state);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
581 this_shn->decode_state = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
582 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
583
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
584 if (this_shn->seek_table)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
585 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
586 free(this_shn->seek_table);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
587 this_shn->seek_table = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
588 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
589
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
590 free(this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
591 this_shn = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
592 if (this_shn_is_shnfile)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
593 shnfile = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
594 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
595 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
596
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
597 shn_file *load_shn(InputPlayback *playback, char *filename, VFSFile *fd)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
598 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
599 shn_file *tmp_file;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
600 shn_seek_entry *first_seek_table;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
601
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
602 shn_debug("Loading file: '%s'", filename);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
603
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
604 if (!(tmp_file = malloc(sizeof(shn_file))))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
605 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
606 shn_debug("Could not allocate memory for SHN data structure");
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
607 return NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
608 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
609
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
610 memset(tmp_file, 0, sizeof(shn_file));
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
611
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
612 tmp_file->vars.fd = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
613 tmp_file->vars.seek_to = -1;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
614 tmp_file->vars.eof = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
615 tmp_file->vars.going = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
616 tmp_file->vars.playback = playback;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
617 tmp_file->vars.seek_table_entries = NO_SEEK_TABLE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
618 tmp_file->vars.bytes_in_buf = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
619 tmp_file->vars.bytes_in_header = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
620 tmp_file->vars.reading_function_code = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
621 tmp_file->vars.initial_file_position = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
622 tmp_file->vars.last_file_position = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
623 tmp_file->vars.last_file_position_no_really = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
624 tmp_file->vars.bytes_read = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
625 tmp_file->vars.actual_bitshift = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
626 tmp_file->vars.actual_maxnlpc = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
627 tmp_file->vars.actual_nmean = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
628 tmp_file->vars.actual_nchan = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
629 tmp_file->vars.seek_offset = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
630
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
631 tmp_file->decode_state = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
632
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
633 tmp_file->wave_header.filename = filename;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
634 tmp_file->wave_header.wave_format = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
635 tmp_file->wave_header.channels = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
636 tmp_file->wave_header.block_align = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
637 tmp_file->wave_header.bits_per_sample = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
638 tmp_file->wave_header.samples_per_sec = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
639 tmp_file->wave_header.avg_bytes_per_sec = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
640 tmp_file->wave_header.rate = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
641 tmp_file->wave_header.header_size = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
642 tmp_file->wave_header.data_size = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
643 tmp_file->wave_header.file_has_id3v2_tag = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
644 tmp_file->wave_header.id3v2_tag_size = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
645
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
646 tmp_file->seek_header.version = NO_SEEK_TABLE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
647 tmp_file->seek_header.shnFileSize = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
648
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
649 tmp_file->seek_trailer.seekTableSize = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
650
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
651 tmp_file->seek_table = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
652
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
653 if (!fd)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
654 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
655 if (!(tmp_file->vars.fd = shn_open_and_discard_id3v2_tag(filename,&tmp_file->wave_header.file_has_id3v2_tag,&tmp_file->wave_header.id3v2_tag_size)))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
656 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
657 shn_debug("Could not open file: '%s'",filename);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
658 shn_unload(tmp_file);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
659 return NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
660 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
661 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
662 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
663 tmp_file->vars.fd = fd;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
664
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
665 if (0 == get_wave_header(tmp_file))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
666 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
667 shn_debug("Unable to read WAVE header from file '%s'",filename);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
668 shn_unload(tmp_file);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
669 return NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
670 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
671
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
672 if (tmp_file->wave_header.file_has_id3v2_tag)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
673 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
674 vfs_fseek(tmp_file->vars.fd,tmp_file->wave_header.id3v2_tag_size,SEEK_SET);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
675 tmp_file->vars.bytes_read += tmp_file->wave_header.id3v2_tag_size;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
676 tmp_file->vars.seek_offset = tmp_file->wave_header.id3v2_tag_size;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
677 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
678 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
679 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
680 vfs_fseek(tmp_file->vars.fd,0,SEEK_SET);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
681 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
682
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
683 if (0 == shn_verify_header(tmp_file))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
684 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
685 shn_debug("Invalid WAVE header in file: '%s'",filename);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
686 shn_unload(tmp_file);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
687 return NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
688 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
689
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
690 if (tmp_file->decode_state)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
691 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
692 free(tmp_file->decode_state);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
693 tmp_file->decode_state = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
694 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
695
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
696 shn_load_seek_table(tmp_file,filename);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
697
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
698 if (NO_SEEK_TABLE != tmp_file->vars.seek_table_entries)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
699 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
700 /* verify seek tables */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
701
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
702 first_seek_table = (shn_seek_entry *)tmp_file->seek_table;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
703
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
704 if (tmp_file->vars.actual_bitshift != shn_uchar_to_ushort_le(first_seek_table->data+22))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
705 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
706 /* initial bitshift value in the file does not match the first bitshift value of the first seektable entry - seeking is broken */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
707 shn_debug("Broken seek table detected (invalid bitshift) - seeking disabled for this file.");
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
708 tmp_file->vars.seek_table_entries = NO_SEEK_TABLE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
709 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
710 else if (tmp_file->vars.actual_nchan > 2)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
711 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
712 /* nchan is greater than the number of such entries stored in a seek table entry - seeking won't work */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
713 shn_debug("Broken seek table detected (nchan %d not in range [1 .. 2]) - seeking disabled for this file.",tmp_file->vars.actual_nchan);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
714 tmp_file->vars.seek_table_entries = NO_SEEK_TABLE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
715 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
716 else if (tmp_file->vars.actual_maxnlpc > 3)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
717 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
718 /* maxnlpc is greater than the number of such entries stored in a seek table entry - seeking won't work */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
719 shn_debug("Broken seek table detected (maxnlpc %d not in range [0 .. 3]) - seeking disabled for this file.",tmp_file->vars.actual_maxnlpc);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
720 tmp_file->vars.seek_table_entries = NO_SEEK_TABLE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
721 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
722 else if (tmp_file->vars.actual_nmean > 4)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
723 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
724 /* nmean is greater than the number of such entries stored in a seek table entry - seeking won't work */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
725 shn_debug("Broken seek table detected (nmean %d not in range [0 .. 4]) - seeking disabled for this file.",tmp_file->vars.actual_nmean);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
726 tmp_file->vars.seek_table_entries = NO_SEEK_TABLE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
727 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
728 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
729 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
730 /* seek table appears to be valid - now adjust byte offsets in seek table to match the file */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
731 tmp_file->vars.seek_offset += tmp_file->vars.initial_file_position - shn_uchar_to_ulong_le(first_seek_table->data+8);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
732
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
733 if (0 != tmp_file->vars.seek_offset)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
734 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
735 shn_debug("Adjusting seek table offsets by %ld bytes due to mismatch between seek table values and input file - seeking might not work correctly.",
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
736 tmp_file->vars.seek_offset);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
737 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
738 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
739 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
740
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
741 shn_debug("Successfully loaded file: '%s'",filename);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
742
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
743 return tmp_file;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
744 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
745
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
746 static int shn_is_our_fd(char *fn, VFSFile *fd)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
747 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
748 char data[4];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
749
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
750 if (vfs_fread((void *)data,1,4,fd) != 4)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
751 return FALSE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
752
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
753 if (memcmp(data,MAGIC,4))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
754 return FALSE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
755
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
756 #if 0
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
757 if (!(tmp_file = load_shn(NULL, filename, fd)))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
758 return FALSE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
759
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
760 shn_unload(tmp_file);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
761 #endif
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
762
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
763 return TRUE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
764 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
765
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
766 void swap_bytes(shn_file *this_shn,int bytes)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
767 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
768 int i;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
769 uchar tmp;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
770
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
771 for (i=0;i<bytes;i=i+2) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
772 tmp = this_shn->vars.buffer[i+1];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
773 this_shn->vars.buffer[i+1] = this_shn->vars.buffer[i];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
774 this_shn->vars.buffer[i] = tmp;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
775 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
776 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
777
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
778 void write_and_wait(shn_file *this_shn,int block_size)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
779 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
780 int bytes_to_write,bytes_in_block,i;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
781 InputPlayback *playback = this_shn->vars.playback;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
782
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
783 if (this_shn->vars.bytes_in_buf < block_size)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
784 return;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
785
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
786 bytes_in_block = min(this_shn->vars.bytes_in_buf, block_size);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
787
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
788 if (bytes_in_block <= 0)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
789 return;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
790
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
791 bytes_to_write = bytes_in_block;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
792 while ((bytes_to_write + bytes_in_block) <= this_shn->vars.bytes_in_buf)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
793 bytes_to_write += bytes_in_block;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
794
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
795 shn_ip.add_vis_pcm(shn_ip.output->written_time(), (this_shn->wave_header.bits_per_sample == 16) ? FMT_S16_LE : FMT_U8,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
796 this_shn->wave_header.channels, bytes_to_write, this_shn->vars.buffer);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
797
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
798 while(shn_ip.output->buffer_free() < bytes_to_write && playback->playing && this_shn->vars.seek_to == -1)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
799 xmms_usleep(10000);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
800
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
801 if(playback->playing && this_shn->vars.seek_to == -1) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
802 if (shn_cfg.swap_bytes)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
803 swap_bytes(this_shn, bytes_to_write);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
804 shn_ip.output->write_audio(this_shn->vars.buffer, bytes_to_write);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
805 } else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
806 return;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
807
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
808 /* shift data from end of buffer to the front */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
809 this_shn->vars.bytes_in_buf -= bytes_to_write;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
810
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
811 for(i=0;i<this_shn->vars.bytes_in_buf;i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
812 this_shn->vars.buffer[i] = this_shn->vars.buffer[i+bytes_to_write];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
813 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
814
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
815 static void *play_loop_shn(void *arg)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
816 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
817 slong **buffer = NULL, **offset = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
818 slong lpcqoffset = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
819 int version = FORMAT_VERSION, bitshift = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
820 int ftype = TYPE_EOF;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
821 char *magic = MAGIC;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
822 int blocksize = DEFAULT_BLOCK_SIZE, nchan = DEFAULT_NCHAN;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
823 int i, chan, nwrap, nskip = DEFAULT_NSKIP;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
824 int *qlpc = NULL, maxnlpc = DEFAULT_MAXNLPC, nmean = UNDEFINED_UINT;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
825 int cmd;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
826 int internal_ftype;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
827 shn_file *this_shn = shnfile;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
828 int blk_size;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
829 int cklen;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
830 uchar tmp;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
831 ulong seekto_offset;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
832 InputPlayback *playback = this_shn->vars.playback;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
833
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
834 restart:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
835
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
836 this_shn->vars.bytes_in_buf = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
837
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
838 if (!init_decode_state(this_shn))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
839 goto exit_thread;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
840
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
841 blk_size = 512 * (this_shn->wave_header.bits_per_sample / 8) * this_shn->wave_header.channels;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
842
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
843 /***********************/
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
844 /* EXTRACT starts here */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
845 /***********************/
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
846
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
847 /* read magic number */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
848 #ifdef STRICT_FORMAT_COMPATABILITY
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
849 if(FORMAT_VERSION < 2)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
850 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
851 for(i = 0; i < strlen(magic); i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
852 if(getc_exit(this_shn->vars.fd) != magic[i]) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
853 shn_error_fatal(this_shn,"Bad magic number");
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
854 goto exit_thread;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
855 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
856
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
857 /* get version number */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
858 version = getc_exit(this_shn->vars.fd);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
859 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
860 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
861 #endif /* STRICT_FORMAT_COMPATABILITY */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
862 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
863 int nscan = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
864
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
865 version = MAX_VERSION + 1;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
866 while(version > MAX_VERSION)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
867 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
868 int byte = vfs_getc(this_shn->vars.fd);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
869 if(byte == EOF) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
870 shn_error_fatal(this_shn,"No magic number");
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
871 goto exit_thread;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
872 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
873 if(magic[nscan] != '\0' && byte == magic[nscan])
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
874 nscan++;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
875 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
876 if(magic[nscan] == '\0' && byte <= MAX_VERSION)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
877 version = byte;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
878 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
879 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
880 if(byte == magic[0])
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
881 nscan = 1;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
882 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
883 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
884 nscan = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
885 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
886 version = MAX_VERSION + 1;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
887 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
888 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
889 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
890
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
891 /* check version number */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
892 if(version > MAX_SUPPORTED_VERSION) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
893 shn_error_fatal(this_shn,"Can't decode version %d", version);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
894 goto exit_thread;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
895 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
896
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
897 /* set up the default nmean, ignoring the command line state */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
898 nmean = (version < 2) ? DEFAULT_V0NMEAN : DEFAULT_V2NMEAN;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
899
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
900 /* initialise the variable length file read for the compressed stream */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
901 var_get_init(this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
902 if (this_shn->vars.fatal_error)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
903 goto exit_thread;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
904
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
905 /* initialise the fixed length file write for the uncompressed stream */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
906 fwrite_type_init(this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
907
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
908 /* get the internal file type */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
909 internal_ftype = UINT_GET(TYPESIZE, this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
910
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
911 /* has the user requested a change in file type? */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
912 if(internal_ftype != ftype) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
913 if(ftype == TYPE_EOF)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
914 ftype = internal_ftype; /* no problems here */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
915 else /* check that the requested conversion is valid */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
916 if(internal_ftype == TYPE_AU1 || internal_ftype == TYPE_AU2 ||
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
917 internal_ftype == TYPE_AU3 || ftype == TYPE_AU1 ||ftype == TYPE_AU2 || ftype == TYPE_AU3) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
918 shn_error_fatal(this_shn,"Not able to perform requested output format conversion");
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
919 goto cleanup;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
920 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
921 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
922
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
923 nchan = UINT_GET(CHANSIZE, this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
924
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
925 /* get blocksize if version > 0 */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
926 if(version > 0)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
927 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
928 int byte;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
929 blocksize = UINT_GET((int) (log((double) DEFAULT_BLOCK_SIZE) / M_LN2),this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
930 maxnlpc = UINT_GET(LPCQSIZE, this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
931 nmean = UINT_GET(0, this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
932 nskip = UINT_GET(NSKIPSIZE, this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
933 for(i = 0; i < nskip; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
934 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
935 byte = uvar_get(XBYTESIZE,this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
936 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
937 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
938 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
939 blocksize = DEFAULT_BLOCK_SIZE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
940
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
941 nwrap = MAX(NWRAP, maxnlpc);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
942
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
943 /* grab some space for the input buffer */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
944 buffer = long2d((ulong) nchan, (ulong) (blocksize + nwrap),this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
945 if (this_shn->vars.fatal_error)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
946 goto exit_thread;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
947 offset = long2d((ulong) nchan, (ulong) MAX(1, nmean),this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
948 if (this_shn->vars.fatal_error) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
949 if (buffer) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
950 free(buffer);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
951 buffer = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
952 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
953 goto exit_thread;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
954 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
955
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
956 for(chan = 0; chan < nchan; chan++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
957 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
958 for(i = 0; i < nwrap; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
959 buffer[chan][i] = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
960 buffer[chan] += nwrap;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
961 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
962
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
963 if(maxnlpc > 0) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
964 qlpc = (int*) pmalloc((ulong) (maxnlpc * sizeof(*qlpc)),this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
965 if (this_shn->vars.fatal_error) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
966 if (buffer) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
967 free(buffer);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
968 buffer = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
969 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
970 if (offset) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
971 free(offset);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
972 buffer = NULL;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
973 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
974 goto exit_thread;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
975 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
976 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
977
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
978 if(version > 1)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
979 lpcqoffset = V2LPCQOFFSET;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
980
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
981 init_offset(offset, nchan, MAX(1, nmean), internal_ftype);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
982
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
983 /* get commands from file and execute them */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
984 chan = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
985 while(1)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
986 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
987 cmd = uvar_get(FNSIZE,this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
988 if (this_shn->vars.fatal_error)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
989 goto cleanup;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
990
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
991 switch(cmd)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
992 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
993 case FN_ZERO:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
994 case FN_DIFF0:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
995 case FN_DIFF1:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
996 case FN_DIFF2:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
997 case FN_DIFF3:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
998 case FN_QLPC:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
999 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1000 slong coffset, *cbuffer = buffer[chan];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1001 int resn = 0, nlpc, j;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1002
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1003 if(cmd != FN_ZERO)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1004 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1005 resn = uvar_get(ENERGYSIZE,this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1006 if (this_shn->vars.fatal_error)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1007 goto cleanup;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1008 /* this is a hack as version 0 differed in definition of var_get */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1009 if(version == 0)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1010 resn--;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1011 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1012
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1013 /* find mean offset : N.B. this code duplicated */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1014 if(nmean == 0)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1015 coffset = offset[chan][0];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1016 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1017 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1018 slong sum = (version < 2) ? 0 : nmean / 2;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1019 for(i = 0; i < nmean; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1020 sum += offset[chan][i];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1021 if(version < 2)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1022 coffset = sum / nmean;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1023 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1024 coffset = ROUNDEDSHIFTDOWN(sum / nmean, bitshift);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1025 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1026
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1027 switch(cmd)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1028 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1029 case FN_ZERO:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1030 for(i = 0; i < blocksize; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1031 cbuffer[i] = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1032 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1033 case FN_DIFF0:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1034 for(i = 0; i < blocksize; i++) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1035 cbuffer[i] = var_get(resn,this_shn) + coffset;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1036 if (this_shn->vars.fatal_error)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1037 goto cleanup;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1038 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1039 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1040 case FN_DIFF1:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1041 for(i = 0; i < blocksize; i++) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1042 cbuffer[i] = var_get(resn,this_shn) + cbuffer[i - 1];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1043 if (this_shn->vars.fatal_error)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1044 goto cleanup;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1045 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1046 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1047 case FN_DIFF2:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1048 for(i = 0; i < blocksize; i++) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1049 cbuffer[i] = var_get(resn,this_shn) + (2 * cbuffer[i - 1] - cbuffer[i - 2]);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1050 if (this_shn->vars.fatal_error)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1051 goto cleanup;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1052 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1053 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1054 case FN_DIFF3:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1055 for(i = 0; i < blocksize; i++) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1056 cbuffer[i] = var_get(resn,this_shn) + 3 * (cbuffer[i - 1] - cbuffer[i - 2]) + cbuffer[i - 3];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1057 if (this_shn->vars.fatal_error)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1058 goto cleanup;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1059 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1060 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1061 case FN_QLPC:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1062 nlpc = uvar_get(LPCQSIZE,this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1063 if (this_shn->vars.fatal_error)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1064 goto cleanup;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1065
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1066 for(i = 0; i < nlpc; i++) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1067 qlpc[i] = var_get(LPCQUANT,this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1068 if (this_shn->vars.fatal_error)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1069 goto cleanup;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1070 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1071 for(i = 0; i < nlpc; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1072 cbuffer[i - nlpc] -= coffset;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1073 for(i = 0; i < blocksize; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1074 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1075 slong sum = lpcqoffset;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1076
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1077 for(j = 0; j < nlpc; j++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1078 sum += qlpc[j] * cbuffer[i - j - 1];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1079 cbuffer[i] = var_get(resn,this_shn) + (sum >> LPCQUANT);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1080 if (this_shn->vars.fatal_error)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1081 goto cleanup;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1082 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1083 if(coffset != 0)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1084 for(i = 0; i < blocksize; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1085 cbuffer[i] += coffset;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1086 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1087 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1088
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1089 /* store mean value if appropriate : N.B. Duplicated code */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1090 if(nmean > 0)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1091 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1092 slong sum = (version < 2) ? 0 : blocksize / 2;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1093
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1094 for(i = 0; i < blocksize; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1095 sum += cbuffer[i];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1096
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1097 for(i = 1; i < nmean; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1098 offset[chan][i - 1] = offset[chan][i];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1099 if(version < 2)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1100 offset[chan][nmean - 1] = sum / blocksize;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1101 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1102 offset[chan][nmean - 1] = (sum / blocksize) << bitshift;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1103 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1104
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1105 /* do the wrap */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1106 for(i = -nwrap; i < 0; i++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1107 cbuffer[i] = cbuffer[i + blocksize];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1108
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1109 fix_bitshift(cbuffer, blocksize, bitshift, internal_ftype);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1110
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1111 if(chan == nchan - 1)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1112 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1113 if (!playback->playing || this_shn->vars.fatal_error)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1114 goto cleanup;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1115
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1116 fwrite_type(buffer, ftype, nchan, blocksize, this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1117
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1118 write_and_wait(this_shn,blk_size);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1119
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1120 if (this_shn->vars.seek_to != -1)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1121 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1122 shn_seek_entry *seek_info;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1123 int j;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1124
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1125 shn_debug("Seeking to %d:%02d",this_shn->vars.seek_to/60,this_shn->vars.seek_to%60);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1126
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1127 seek_info = shn_seek_entry_search(this_shn->seek_table,this_shn->vars.seek_to * (ulong)this_shn->wave_header.samples_per_sec,0,
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1128 (ulong)(this_shn->vars.seek_table_entries - 1),this_shn->vars.seek_resolution);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1129
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1130 /* loop through number of channels in this file */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1131 for (i=0;i<nchan;i++) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1132 /* load the three sample buffer values for this channel */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1133 for (j=0;j<3;j++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1134 buffer[i][j-3] = shn_uchar_to_slong_le(seek_info->data+32+12*i-4*j);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1135
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1136 /* load the variable number of offset history values for this channel */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1137 for (j=0;j<MAX(1,nmean);j++)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1138 offset[i][j] = shn_uchar_to_slong_le(seek_info->data+48+16*i+4*j);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1139 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1140
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1141 bitshift = shn_uchar_to_ushort_le(seek_info->data+22);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1142
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1143 seekto_offset = shn_uchar_to_ulong_le(seek_info->data+8) + this_shn->vars.seek_offset;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1144
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1145 vfs_fseek(this_shn->vars.fd,(slong)seekto_offset,SEEK_SET);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1146 vfs_fread((uchar*) this_shn->decode_state->getbuf, 1, BUFSIZ, this_shn->vars.fd);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1147
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1148 this_shn->decode_state->getbufp = this_shn->decode_state->getbuf + shn_uchar_to_ushort_le(seek_info->data+14);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1149 this_shn->decode_state->nbitget = shn_uchar_to_ushort_le(seek_info->data+16);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1150 this_shn->decode_state->nbyteget = shn_uchar_to_ushort_le(seek_info->data+12);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1151 this_shn->decode_state->gbuffer = shn_uchar_to_ulong_le(seek_info->data+18);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1152
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1153 this_shn->vars.bytes_in_buf = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1154
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1155 shn_ip.output->flush(this_shn->vars.seek_to * 1000);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1156 this_shn->vars.seek_to = -1;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1157 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1158
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1159 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1160 chan = (chan + 1) % nchan;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1161 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1162 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1163
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1164 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1165
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1166 case FN_QUIT:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1167 /* empty out last of buffer */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1168 write_and_wait(this_shn,this_shn->vars.bytes_in_buf);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1169
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1170 playback->eof = TRUE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1171
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1172 while (1)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1173 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1174 if (!playback->playing)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1175 goto finish;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1176 if (this_shn->vars.seek_to != -1)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1177 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1178 var_get_quit(this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1179 fwrite_type_quit(this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1180
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1181 if (buffer) free((void *) buffer);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1182 if (offset) free((void *) offset);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1183 if(maxnlpc > 0 && qlpc)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1184 free((void *) qlpc);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1185
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1186 vfs_fseek(this_shn->vars.fd,0,SEEK_SET);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1187 goto restart;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1188 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1189 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1190 xmms_usleep(10000);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1191 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1192
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1193 goto cleanup;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1194 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1195
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1196 case FN_BLOCKSIZE:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1197 blocksize = UINT_GET((int) (log((double) blocksize) / M_LN2), this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1198 if (this_shn->vars.fatal_error)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1199 goto cleanup;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1200 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1201 case FN_BITSHIFT:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1202 bitshift = uvar_get(BITSHIFTSIZE,this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1203 if (this_shn->vars.fatal_error)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1204 goto cleanup;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1205 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1206 case FN_VERBATIM:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1207 cklen = uvar_get(VERBATIM_CKSIZE_SIZE,this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1208 if (this_shn->vars.fatal_error)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1209 goto cleanup;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1210
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1211 while (cklen--) {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1212 tmp = (uchar)uvar_get(VERBATIM_BYTE_SIZE,this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1213 if (this_shn->vars.fatal_error)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1214 goto cleanup;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1215 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1216
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1217 break;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1218
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1219 default:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1220 shn_error_fatal(this_shn,"Sanity check fails trying to decode function: %d",cmd);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1221 goto cleanup;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1222 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1223 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1224
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1225 cleanup:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1226
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1227 write_and_wait(this_shn,this_shn->vars.bytes_in_buf);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1228 shn_ip.output->buffer_free();
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1229 shn_ip.output->buffer_free();
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1230 xmms_usleep(10000);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1231
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1232 finish:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1233
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1234 this_shn->vars.seek_to = -1;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1235 playback->eof = TRUE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1236
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1237 /* wind up */
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1238 var_get_quit(this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1239 fwrite_type_quit(this_shn);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1240
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1241 if (buffer) free((void *) buffer);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1242 if (offset) free((void *) offset);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1243 if(maxnlpc > 0 && qlpc)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1244 free((void *) qlpc);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1245
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1246 exit_thread:
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1247
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1248 pthread_exit(NULL);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1249 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1250
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1251 static void shn_play(InputPlayback *playback)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1252 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1253 char *name, *temp;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1254 char *filename = playback->filename;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1255
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1256 audio_error = FALSE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1257
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1258 if (!(shnfile = load_shn(playback, playback->filename, NULL)))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1259 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1260 shn_debug("Could not load file for playing: '%s'", playback->filename);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1261 return;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1262 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1263
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1264 vfs_fseek(shnfile->vars.fd,0,SEEK_SET);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1265
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1266 playback->playing = TRUE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1267
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1268 if (shn_ip.output->open_audio((shnfile->wave_header.bits_per_sample == 16) ? FMT_S16_LE : FMT_U8, shnfile->wave_header.samples_per_sec, shnfile->wave_header.channels) == 0)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1269 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1270 audio_error = TRUE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1271 shn_debug("Could not open audio device for playback (check your output plugin configuration)");
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1272 return;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1273 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1274 temp = strrchr(filename, '/');
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1275 if (!temp)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1276 temp = filename;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1277 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1278 temp++;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1279 name = malloc(strlen(temp) + 1);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1280 strcpy(name, temp);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1281 if (shn_filename_contains_a_dot(name))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1282 *(strrchr(name,'.')) = '\0';
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1283 shn_ip.set_info(name, 1000 * shnfile->wave_header.length, 8 * shnfile->wave_header.rate, shnfile->wave_header.samples_per_sec, shnfile->wave_header.channels);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1284 free(name);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1285 shnfile->vars.seek_to = -1;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1286 pthread_create(&decode_thread, NULL, play_loop_shn, NULL);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1287 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1288
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1289 static void shn_stop(InputPlayback *playback)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1290 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1291 int was_fatal;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1292 char error_msg[BUF_SIZE];
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1293
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1294 if (!shnfile)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1295 return;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1296
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1297 if ((was_fatal = shnfile->vars.fatal_error))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1298 shn_snprintf(error_msg,BUF_SIZE,"%s.\nAffected file was:\n%s",shnfile->vars.fatal_error_msg,shnfile->wave_header.filename);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1299
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1300 if (playback->playing || was_fatal)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1301 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1302 playback->playing = FALSE;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1303 pthread_join(decode_thread, NULL);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1304 shn_ip.output->close_audio();
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1305 shn_unload(shnfile);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1306 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1307
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1308 if (was_fatal)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1309 shn_error(error_msg);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1310 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1311
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1312 static void shn_pause(InputPlayback *playback, short p)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1313 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1314 playback->output->pause(p);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1315 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1316
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1317 static void shn_seek(InputPlayback *playback, int time)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1318 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1319 if (NULL == shnfile)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1320 return;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1321
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1322 if (shnfile->vars.seek_table_entries == NO_SEEK_TABLE)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1323 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1324 shn_error("Cannot seek to %d:%02d because there is no seek information for this file.",time/60,time%60);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1325 return;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1326 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1327
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1328 shnfile->vars.seek_to = time;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1329
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1330 while (shnfile->vars.seek_to != -1)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1331 xmms_usleep(10000);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1332 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1333
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1334 static void shn_get_file_info(char *filename, char **title, int *length)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1335 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1336 char *name, *temp;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1337 shn_file *tmp_file;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1338
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1339 temp = strrchr(filename, '/');
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1340 if (!temp)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1341 temp = filename;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1342 else
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1343 temp++;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1344
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1345 name = g_malloc(strlen(temp) + 1);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1346 strcpy(name, temp);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1347
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1348 if (shn_filename_contains_a_dot(name))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1349 *(strrchr(name,'.')) = '\0';
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1350
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1351 *title = name;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1352
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1353 *length = 0;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1354
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1355 if (!(tmp_file = load_shn(NULL, filename, NULL)))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1356 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1357 shn_debug("Could not get information from file: '%s'",filename);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1358 return;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1359 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1360
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1361 *length = 1000 * tmp_file->wave_header.length;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1362
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1363 shn_unload(tmp_file);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1364 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1365
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1366 static void shn_display_file_info(char *filename)
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1367 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1368 shn_file *tmp_file;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1369
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1370 if (!(tmp_file = load_shn(NULL, filename, NULL)))
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1371 {
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1372 shn_debug("Could not get information from file: '%s'",filename);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1373 return;
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1374 }
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1375
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1376 shn_display_info(tmp_file);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1377
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1378 shn_unload(tmp_file);
|
William Pitcock <nenolod@atheme-project.org>
parents:
diff
changeset
|
1379 }
|