Mercurial > audlegacy-plugins
annotate src/wavpack/libwavpack.cxx @ 1501:04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
This bumps our required version of libwavpack to 4.4.
author | William Pitcock <nenolod@atheme-project.org> |
---|---|
date | Fri, 17 Aug 2007 11:40:30 -0500 |
parents | db616ccdd40c |
children | 3a252050736c 2ed7413c199a |
rev | line source |
---|---|
1436
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
1 #include <string> |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
2 |
109 | 3 #include <assert.h> |
4 #include <string.h> | |
5 #include <stdio.h> | |
6 #include <stdlib.h> | |
7 #include <unistd.h> | |
291
93c0da3f7a86
[svn] - make wavpack/wavpack.h include forced extern "C".
nenolod
parents:
284
diff
changeset
|
8 extern "C" { |
284
72f0de06bb56
[svn] - wavpack/wputils.h is deprecated, wavpack/wavpack.h should be used instead.
nenolod
parents:
264
diff
changeset
|
9 #include <wavpack/wavpack.h> |
109 | 10 #include <audacious/plugin.h> |
111 | 11 #include <audacious/output.h> |
109 | 12 #include <audacious/configdb.h> |
1436
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
13 #include <audacious/main.h> |
109 | 14 #include <audacious/util.h> |
233
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
15 #include <audacious/vfs.h> |
109 | 16 } |
17 #include <glib.h> | |
18 #include <gtk/gtk.h> | |
19 #include <iconv.h> | |
20 #include <math.h> | |
21 #include "tags.h" | |
434
7385182ae4b8
[svn] - add missing config.h inclusion for wavpack, null and metronom plugin
giacomo
parents:
372
diff
changeset
|
22 #include "../../config.h" |
109 | 23 #ifndef M_LN10 |
24 #define M_LN10 2.3025850929940456840179914546843642 | |
25 #endif | |
26 | |
112 | 27 #ifdef DEBUG |
28 # define DBG(format, args...) fprintf(stderr, format, ## args) | |
29 #else | |
30 # define DBG(format, args...) | |
31 #endif | |
32 | |
109 | 33 #define BUFFER_SIZE 256 // read buffer size, in samples |
34 | |
35 static void wv_load_config(); | |
253
ab24cfe495e0
[svn] Port to NewVFS file probe & add explicit cast to silence warning, thanks to spb.
chainsaw
parents:
247
diff
changeset
|
36 static int wv_is_our_fd(gchar *filename, VFSFile *file); |
566 | 37 static void wv_play(InputPlayback *); |
38 static void wv_stop(InputPlayback *); | |
39 static void wv_pause(InputPlayback *, short); | |
40 static void wv_seek(InputPlayback *, int); | |
41 static int wv_get_time(InputPlayback *); | |
109 | 42 static void wv_get_song_info(char *, char **, int *); |
43 static char *generate_title(const char *, WavpackContext *ctx); | |
44 static double isSeek; | |
45 static short paused; | |
46 static bool killDecodeThread; | |
47 static bool AudioError; | |
48 static GThread *thread_handle; | |
1436
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
49 static Tuple *wv_get_song_tuple(char *); |
109 | 50 |
51 // in ui.cpp | |
52 void wv_configure(); | |
53 void wv_about_box(void); | |
54 void wv_file_info_box(char *); | |
55 extern gboolean clipPreventionEnabled; | |
56 extern gboolean dynBitrateEnabled; | |
57 extern gboolean replaygainEnabled; | |
58 extern gboolean albumReplaygainEnabled; | |
59 extern gboolean openedAudio; | |
60 | |
1044
b1128efde471
[svn] - get rid of all warnings gcc 4.2.0 emits with my build configuration.
yaz
parents:
566
diff
changeset
|
61 const gchar *wv_fmts[] = { "wv", NULL }; |
372
a157306caf03
[svn] - finalize the plugin-side of the extension-assist ABI
nenolod
parents:
368
diff
changeset
|
62 |
109 | 63 InputPlugin mod = { |
64 NULL, //handle | |
65 NULL, //filename | |
1185 | 66 (gchar *)"WavPack Audio Plugin", |
109 | 67 wv_load_config, |
68 wv_about_box, | |
69 wv_configure, | |
332
626f9f4d79a8
[svn] Remove old-style is_our_file() where a new-style is_our_fd() exists
kiyoshi
parents:
291
diff
changeset
|
70 NULL, |
109 | 71 NULL, //no use |
72 wv_play, | |
73 wv_stop, | |
74 wv_pause, | |
75 wv_seek, | |
76 NULL, //set eq | |
77 wv_get_time, | |
78 NULL, //get volume | |
79 NULL, //set volume | |
80 NULL, //cleanup | |
81 NULL, //obsolete | |
82 NULL, //add_vis | |
83 NULL, | |
84 NULL, | |
85 wv_get_song_info, | |
263 | 86 wv_file_info_box, //info box |
109 | 87 NULL, //output |
114 | 88 wv_get_song_tuple, |
253
ab24cfe495e0
[svn] Port to NewVFS file probe & add explicit cast to silence warning, thanks to spb.
chainsaw
parents:
247
diff
changeset
|
89 NULL, |
ab24cfe495e0
[svn] Port to NewVFS file probe & add explicit cast to silence warning, thanks to spb.
chainsaw
parents:
247
diff
changeset
|
90 NULL, |
ab24cfe495e0
[svn] Port to NewVFS file probe & add explicit cast to silence warning, thanks to spb.
chainsaw
parents:
247
diff
changeset
|
91 wv_is_our_fd, |
1044
b1128efde471
[svn] - get rid of all warnings gcc 4.2.0 emits with my build configuration.
yaz
parents:
566
diff
changeset
|
92 (gchar **)wv_fmts, |
109 | 93 }; |
94 | |
233
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
95 int32_t read_bytes (void *id, void *data, int32_t bcount) |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
96 { |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
97 return vfs_fread (data, 1, bcount, (VFSFile *) id); |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
98 } |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
99 |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
100 uint32_t get_pos (void *id) |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
101 { |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
102 return vfs_ftell ((VFSFile *) id); |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
103 } |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
104 |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
105 int set_pos_abs (void *id, uint32_t pos) |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
106 { |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
107 return vfs_fseek ((VFSFile *) id, pos, SEEK_SET); |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
108 } |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
109 |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
110 int set_pos_rel (void *id, int32_t delta, int mode) |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
111 { |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
112 return vfs_fseek ((VFSFile *) id, delta, mode); |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
113 } |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
114 |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
115 int push_back_byte (void *id, int c) |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
116 { |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
117 return vfs_ungetc (c, (VFSFile *) id); |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
118 } |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
119 |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
120 uint32_t get_length (void *id) |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
121 { |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
122 VFSFile *file = (VFSFile *) id; |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
123 uint32_t sz = 0; |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
124 |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
125 if (file == NULL) |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
126 return 0; |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
127 |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
128 vfs_fseek(file, 0, SEEK_END); |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
129 sz = vfs_ftell(file); |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
130 vfs_fseek(file, 0, SEEK_SET); |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
131 |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
132 return sz; |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
133 } |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
134 |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
135 /* XXX streams?? */ |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
136 int can_seek (void *id) |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
137 { |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
138 return 1; |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
139 } |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
140 |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
141 int32_t write_bytes (void *id, void *data, int32_t bcount) |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
142 { |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
143 return vfs_fwrite (data, 1, bcount, (VFSFile *) id); |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
144 } |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
145 |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
146 WavpackStreamReader reader = { |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
147 read_bytes, get_pos, set_pos_abs, set_pos_rel, push_back_byte, get_length, can_seek, |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
148 write_bytes |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
149 }; |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
150 |
109 | 151 class WavpackDecoder |
152 { | |
153 public: | |
154 InputPlugin *mod; | |
155 int32_t *input; | |
156 int16_t *output; | |
157 int sample_rate; | |
158 int num_channels; | |
159 WavpackContext *ctx; | |
160 char error_buff[4096]; // TODO: fixme! | |
233
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
161 VFSFile *wv_Input, *wvc_Input; |
109 | 162 |
163 WavpackDecoder(InputPlugin *mod) : mod(mod) | |
164 { | |
165 ctx = NULL; | |
166 input = NULL; | |
167 output = NULL; | |
168 } | |
169 | |
170 ~WavpackDecoder() | |
171 { | |
172 if (input != NULL) { | |
173 free(input); | |
174 input = NULL; | |
175 } | |
176 if (output != NULL) { | |
177 free(output); | |
178 output = NULL; | |
179 } | |
180 if (ctx != NULL) { | |
233
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
181 vfs_fclose(wv_Input); |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
182 vfs_fclose(wvc_Input); |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
183 g_free(ctx); |
109 | 184 ctx = NULL; |
185 } | |
186 } | |
187 | |
188 bool attach(const char *filename) | |
189 { | |
233
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
190 wv_Input = vfs_fopen(filename, "rb"); |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
191 |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
192 char *corrFilename = g_strconcat(filename, "c", NULL); |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
193 |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
194 wvc_Input = vfs_fopen(corrFilename, "rb"); |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
195 |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
196 g_free(corrFilename); |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
197 |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
198 ctx = WavpackOpenFileInputEx(&reader, wv_Input, wvc_Input, error_buff, OPEN_TAGS | OPEN_WVC, 0); |
109 | 199 |
200 if (ctx == NULL) { | |
201 return false; | |
202 } | |
203 | |
237 | 204 return true; |
205 } | |
206 | |
1501
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
207 bool attach(gchar *filename, VFSFile *wv_Input) |
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
208 { |
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
209 vfs_dup(wv_Input); |
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
210 |
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
211 ctx = WavpackOpenFileInputEx(&reader, wv_Input, NULL, error_buff, OPEN_TAGS, 0); |
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
212 |
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
213 if (ctx == NULL) |
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
214 return false; |
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
215 |
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
216 return true; |
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
217 } |
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
218 |
237 | 219 bool attach_to_play(const char *filename) |
220 { | |
221 wv_Input = vfs_fopen(filename, "rb"); | |
222 | |
223 char *corrFilename = g_strconcat(filename, "c", NULL); | |
224 | |
225 wvc_Input = vfs_fopen(corrFilename, "rb"); | |
226 | |
227 g_free(corrFilename); | |
228 | |
229 ctx = WavpackOpenFileInputEx(&reader, wv_Input, wvc_Input, error_buff, OPEN_TAGS | OPEN_WVC, 0); | |
230 | |
1501
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
231 if (ctx == NULL) |
237 | 232 return false; |
233 | |
109 | 234 sample_rate = WavpackGetSampleRate(ctx); |
235 num_channels = WavpackGetNumChannels(ctx); | |
236 input = (int32_t *)calloc(BUFFER_SIZE, num_channels * sizeof(int32_t)); | |
237 output = (int16_t *)calloc(BUFFER_SIZE, num_channels * sizeof(int16_t)); | |
238 mod->set_info(generate_title(filename, ctx), | |
239 (int) (WavpackGetNumSamples(ctx) / sample_rate) * 1000, | |
240 (int) WavpackGetAverageBitrate(ctx, num_channels), | |
241 (int) sample_rate, num_channels); | |
242 return true; | |
243 } | |
244 | |
245 bool open_audio() | |
246 { | |
112 | 247 return mod->output->open_audio(FMT_S16_NE, sample_rate, num_channels); |
109 | 248 } |
249 | |
250 void process_buffer(size_t num_samples) | |
251 { | |
1501
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
252 /* TODO: dithering */ |
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
253 for (int i = 0; i < num_samples * num_channels; i++) |
109 | 254 output[i] = input[i]; |
1501
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
255 |
112 | 256 produce_audio(mod->output->output_time(), FMT_S16_NE, |
111 | 257 num_channels, |
258 num_samples * num_channels * sizeof(int16_t), | |
259 output, | |
260 NULL); | |
109 | 261 } |
262 }; | |
263 | |
1080 | 264 InputPlugin *wv_iplist[] = { &mod, NULL }; |
265 | |
1395
761e17b23e0c
added Discovery plugin type
Cristi Magherusan <majeru@atheme-project.org>
parents:
1354
diff
changeset
|
266 DECLARE_PLUGIN(wavpack, NULL, NULL, wv_iplist, NULL, NULL, NULL, NULL,NULL); |
109 | 267 |
268 static int | |
253
ab24cfe495e0
[svn] Port to NewVFS file probe & add explicit cast to silence warning, thanks to spb.
chainsaw
parents:
247
diff
changeset
|
269 wv_is_our_fd(gchar *filename, VFSFile *file) |
109 | 270 { |
1501
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
271 WavpackDecoder d(&mod); |
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
272 |
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
273 if (d.attach(filename, file)) |
253
ab24cfe495e0
[svn] Port to NewVFS file probe & add explicit cast to silence warning, thanks to spb.
chainsaw
parents:
247
diff
changeset
|
274 return TRUE; |
1501
04f8c7624ea3
Support Wavpack ".exe" executables, by using the Wavpack decoder to validate.
William Pitcock <nenolod@atheme-project.org>
parents:
1465
diff
changeset
|
275 |
109 | 276 return FALSE; |
277 } | |
278 | |
279 void | |
280 load_tag(ape_tag *tag, WavpackContext *ctx) | |
281 { | |
282 memset(tag, 0, sizeof(ape_tag)); | |
283 WavpackGetTagItem(ctx, "Album", tag->album, sizeof(tag->album)); | |
284 WavpackGetTagItem(ctx, "Artist", tag->artist, sizeof(tag->artist)); | |
285 WavpackGetTagItem(ctx, "Comment", tag->comment, sizeof(tag->comment)); | |
286 WavpackGetTagItem(ctx, "Genre", tag->genre, sizeof(tag->genre)); | |
287 WavpackGetTagItem(ctx, "Title", tag->title, sizeof(tag->title)); | |
288 WavpackGetTagItem(ctx, "Track", tag->track, sizeof(tag->track)); | |
289 WavpackGetTagItem(ctx, "Year", tag->year, sizeof(tag->year)); | |
290 } | |
291 | |
292 static void * | |
293 end_thread() | |
294 { | |
295 return 0; | |
296 } | |
297 | |
298 static void * | |
299 DecodeThread(void *a) | |
300 { | |
301 ape_tag tag; | |
302 char *filename = (char *) a; | |
303 int bps_updateCounter = 0; | |
304 int bps; | |
305 int i; | |
306 WavpackDecoder d(&mod); | |
307 | |
237 | 308 if (!d.attach_to_play(filename)) { |
109 | 309 killDecodeThread = true; |
310 return end_thread(); | |
311 } | |
312 bps = WavpackGetBytesPerSample(d.ctx) * d.num_channels; | |
313 DBG("reading %s at %d rate with %d channels\n", filename, d.sample_rate, d.num_channels); | |
314 | |
315 if (!d.open_audio()) { | |
1128 | 316 DBG("error opening audio channel\n"); |
109 | 317 killDecodeThread = true; |
318 AudioError = true; | |
319 openedAudio = false; | |
320 } | |
321 else { | |
1128 | 322 DBG("opened audio channel\n"); |
109 | 323 openedAudio = true; |
324 } | |
325 unsigned status; | |
326 char *display = generate_title(filename, d.ctx); | |
327 int length = (int) (1000 * WavpackGetNumSamples(d.ctx)); | |
328 | |
329 while (!killDecodeThread) { | |
330 if (isSeek != -1) { | |
331 DBG("seeking to position %d\n", isSeek); | |
253
ab24cfe495e0
[svn] Port to NewVFS file probe & add explicit cast to silence warning, thanks to spb.
chainsaw
parents:
247
diff
changeset
|
332 WavpackSeekSample(d.ctx, (int)(isSeek * d.sample_rate)); |
109 | 333 isSeek = -1; |
334 } | |
335 if (paused == 0 | |
336 && (mod.output->buffer_free() >= | |
337 (1152 * 2 * | |
338 (16 / 8)) << (mod.output->buffer_playing()? 1 : 0))) { | |
339 status = | |
340 WavpackUnpackSamples(d.ctx, d.input, BUFFER_SIZE); | |
341 if (status == (unsigned) (-1)) { | |
342 printf("wavpack: Error decoding file.\n"); | |
343 break; | |
344 } | |
345 else if (status == 0) { | |
346 killDecodeThread = true; | |
347 break; | |
348 } | |
349 else { | |
350 d.process_buffer(status); | |
351 } | |
352 } | |
353 else { | |
354 xmms_usleep(10000); | |
355 } | |
356 } | |
357 return end_thread(); | |
358 } | |
359 | |
360 static void | |
566 | 361 wv_play(InputPlayback *data) |
109 | 362 { |
363 paused = 0; | |
364 isSeek = -1; | |
365 killDecodeThread = false; | |
366 AudioError = false; | |
1354
b670d1f3c2e4
wavpack: new threading model
William Pitcock <nenolod@atheme-project.org>
parents:
1185
diff
changeset
|
367 thread_handle = g_thread_self(); |
1447
195b5657303e
updated input plugins to use set_pb_ready to signal to the core that they're ready for playback
Giacomo Lozito <james@develia.org>
parents:
1445
diff
changeset
|
368 data->set_pb_ready(data); |
1354
b670d1f3c2e4
wavpack: new threading model
William Pitcock <nenolod@atheme-project.org>
parents:
1185
diff
changeset
|
369 DecodeThread((void *) data->filename); |
109 | 370 return; |
371 } | |
372 | |
1436
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
373 static std::string |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
374 WavpackPluginGetQualityString(WavpackContext *ctx) |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
375 { |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
376 int mode = WavpackGetMode(ctx); |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
377 |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
378 if (mode & MODE_LOSSLESS) |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
379 return "lossless"; |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
380 |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
381 if (mode & MODE_HYBRID) |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
382 return "lossy (hybrid)"; |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
383 |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
384 return "lossy"; |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
385 } |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
386 |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
387 static Tuple * |
114 | 388 tuple_from_WavpackContext(const char *fn, WavpackContext *ctx) |
389 { | |
390 ape_tag tag; | |
1436
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
391 Tuple *ti; |
114 | 392 int sample_rate = WavpackGetSampleRate(ctx); |
393 | |
1436
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
394 ti = tuple_new_from_filename(fn); |
114 | 395 |
396 load_tag(&tag, ctx); | |
397 | |
1436
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
398 tuple_associate_string(ti, "title", tag.title); |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
399 tuple_associate_string(ti, "artist", tag.artist); |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
400 tuple_associate_string(ti, "album", tag.album); |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
401 tuple_associate_string(ti, "genre", tag.genre); |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
402 tuple_associate_string(ti, "comment", tag.comment); |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
403 tuple_associate_string(ti, "date", tag.year); |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
404 tuple_associate_string(ti, "quality", WavpackPluginGetQualityString(ctx).c_str()); |
1445
580f1b971518
we're looking for the name of the codec here, not tag.year(), thanks.
William Pitcock <nenolod@atheme-project.org>
parents:
1436
diff
changeset
|
405 tuple_associate_string(ti, "codec", "WavPack"); |
1436
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
406 |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
407 tuple_associate_int(ti, "track-number", atoi(tag.track)); |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
408 tuple_associate_int(ti, "year", atoi(tag.year)); |
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
409 tuple_associate_int(ti, "length", (int)(WavpackGetNumSamples(ctx) / sample_rate) * 1000); |
114 | 410 |
411 return ti; | |
412 } | |
413 | |
109 | 414 static char * |
415 generate_title(const char *fn, WavpackContext *ctx) | |
416 { | |
417 static char *displaytitle = NULL; | |
1436
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
418 Tuple *ti; |
109 | 419 |
114 | 420 ti = tuple_from_WavpackContext(fn, ctx); |
109 | 421 |
1436
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
422 displaytitle = tuple_formatter_process_string(ti, cfg.gentitle_format); |
115
2e77e3fdd3c1
[svn] - make sure the tuple data is copied, not referenced (oops)
nenolod
parents:
114
diff
changeset
|
423 if (!displaytitle || *displaytitle == '\0') |
2e77e3fdd3c1
[svn] - make sure the tuple data is copied, not referenced (oops)
nenolod
parents:
114
diff
changeset
|
424 displaytitle = g_strdup(fn); |
114 | 425 |
1465
db616ccdd40c
use tuple_free(x) in place of mowgli_object_unref(x)
Giacomo Lozito <james@develia.org>
parents:
1447
diff
changeset
|
426 tuple_free((void *) ti); |
109 | 427 |
428 return displaytitle; | |
429 } | |
430 | |
1436
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
431 static Tuple * |
114 | 432 wv_get_song_tuple(char *filename) |
433 { | |
1436
0ff7d08693f6
wavpack: update to new tuple API, use std::string more.
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
434 Tuple *ti; |
233
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
435 WavpackDecoder d(&mod); |
114 | 436 |
233
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
437 if (!d.attach(filename)) { |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
438 printf("wavpack: Error opening file: \"%s\"\n", filename); |
114 | 439 return NULL; |
440 } | |
441 | |
233
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
442 ti = tuple_from_WavpackContext(filename, d.ctx); |
114 | 443 |
444 return ti; | |
445 } | |
446 | |
109 | 447 static void |
448 wv_get_song_info(char *filename, char **title, int *length) | |
449 { | |
450 assert(filename != NULL); | |
233
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
451 WavpackDecoder d(&mod); |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
452 |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
453 if (!d.attach(filename)) { |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
454 printf("wavpack: Error opening file: \"%s\"\n", filename); |
109 | 455 return; |
456 } | |
233
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
457 |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
458 int sample_rate = WavpackGetSampleRate(d.ctx); |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
459 int num_channels = WavpackGetNumChannels(d.ctx); |
109 | 460 DBG("reading %s at %d rate with %d channels\n", filename, sample_rate, num_channels); |
461 | |
233
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
462 *length = (int)(WavpackGetNumSamples(d.ctx) / sample_rate) * 1000, |
7b7660c9f31c
[svn] - rewrite to take advantage of already existant object-oriented framework
nenolod
parents:
130
diff
changeset
|
463 *title = generate_title(filename, d.ctx); |
109 | 464 DBG("title for %s = %s\n", filename, *title); |
465 } | |
466 | |
467 static int | |
566 | 468 wv_get_time(InputPlayback *data) |
109 | 469 { |
566 | 470 if (data->output == NULL) |
109 | 471 return -1; |
472 if (AudioError) | |
473 return -2; | |
566 | 474 if (killDecodeThread && !data->output->buffer_playing()) |
109 | 475 return -1; |
566 | 476 return data->output->output_time(); |
109 | 477 } |
478 | |
479 static void | |
566 | 480 wv_seek(InputPlayback *data, int sec) |
109 | 481 { |
566 | 482 isSeek = sec; |
483 data->output->flush((int) (1000 * isSeek)); | |
109 | 484 } |
485 | |
486 static void | |
566 | 487 wv_pause(InputPlayback *data, short pause) |
488 { | |
489 data->output->pause(paused = pause); | |
490 } | |
491 | |
492 static void | |
493 wv_stop(InputPlayback *data) | |
109 | 494 { |
495 killDecodeThread = true; | |
496 if (thread_handle != 0) { | |
497 g_thread_join(thread_handle); | |
498 if (openedAudio) { | |
499 mod.output->buffer_free(); | |
500 mod.output->close_audio(); | |
501 } | |
502 openedAudio = false; | |
503 if (AudioError) | |
504 printf("Could not open Audio\n"); | |
505 } | |
506 | |
507 } | |
508 | |
509 static void | |
510 wv_load_config() | |
511 { | |
512 ConfigDb *cfg; | |
513 | |
514 cfg = bmp_cfg_db_open(); | |
515 | |
516 bmp_cfg_db_get_bool(cfg, "wavpack", "clip_prevention", | |
517 &clipPreventionEnabled); | |
518 bmp_cfg_db_get_bool(cfg, "wavpack", "album_replaygain", | |
519 &albumReplaygainEnabled); | |
520 bmp_cfg_db_get_bool(cfg, "wavpack", "dyn_bitrate", &dynBitrateEnabled); | |
521 bmp_cfg_db_get_bool(cfg, "wavpack", "replaygain", &replaygainEnabled); | |
522 bmp_cfg_db_close(cfg); | |
523 | |
524 openedAudio = false; | |
525 } |