~ubuntu-branches/ubuntu/raring/flac/raring

« back to all changes in this revision

Viewing changes to src/plugin_winamp2/in_flac.c

  • Committer: Bazaar Package Importer
  • Author(s): Joshua Kwan
  • Date: 2007-05-29 22:56:36 UTC
  • mto: (8.1.1 lenny)
  • mto: This revision was merged to the branch mainline in revision 9.
  • Revision ID: james.westby@ubuntu.com-20070529225636-p8lkii0r0kp50pns
Tags: upstream-1.1.4
ImportĀ upstreamĀ versionĀ 1.1.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* in_flac - Winamp2 FLAC input plugin
2
 
 * Copyright (C) 2000,2001,2002,2003,2004,2005  Josh Coalson
3
 
 *
4
 
 * This program is free software; you can redistribute it and/or
5
 
 * modify it under the terms of the GNU General Public License
6
 
 * as published by the Free Software Foundation; either version 2
7
 
 * of the License, or (at your option) any later version.
8
 
 *
9
 
 * This program is distributed in the hope that it will be useful,
 
2
 * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007  Josh Coalson
 
3
 *
 
4
 * This library is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU Lesser General Public
 
6
 * License as published by the Free Software Foundation; either
 
7
 * version 2.1 of the License, or (at your option) any later version.
 
8
 *
 
9
 * This library is distributed in the hope that it will be useful,
10
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
 * GNU General Public License for more details.
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
 * Lesser General Public License for more details.
13
13
 *
14
 
 * You should have received a copy of the GNU General Public License
15
 
 * along with this program; if not, write to the Free Software
16
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
14
 * You should have received a copy of the GNU Lesser General Public
 
15
 * License along with this library; if not, write to the Free Software
 
16
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17
17
 */
18
18
 
 
19
#if HAVE_CONFIG_H
 
20
#  include <config.h>
 
21
#endif
 
22
 
19
23
#include <windows.h>
 
24
#include <limits.h> /* for INT_MAX */
20
25
#include <stdio.h>
21
26
 
22
27
#include "winamp2/in2.h"
23
 
#include "config.h"
 
28
#include "configure.h"
24
29
#include "infobox.h"
25
30
#include "tagz.h"
26
31
 
27
 
#define PLUGIN_VERSION          "1.1.2"
 
32
#define PLUGIN_VERSION          "1.1.4"
28
33
 
29
34
static In_Module mod_;                      /* the input module (declared near the bottom of this file) */
30
35
static char lastfn_[MAX_PATH];              /* currently playing file (used for getting info on the current file) */
31
36
flac_config_t flac_cfg;
32
37
 
33
 
static file_info_struct file_info_;
 
38
static stream_data_struct stream_data_;
34
39
static int paused;
35
 
static FLAC__FileDecoder *decoder_;
 
40
static FLAC__StreamDecoder *decoder_;
36
41
static char sample_buffer_[SAMPLES_PER_WRITE * FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS * (24/8) * 2];
37
42
/* (24/8) for max bytes per sample, and 2 for DSPs */
38
43
 
45
50
 
46
51
static void init()
47
52
{
48
 
        decoder_ = FLAC__file_decoder_new();
 
53
        decoder_ = FLAC__stream_decoder_new();
49
54
        strcpy(lastfn_, "");
50
55
 
51
56
        InitConfig();
76
81
        if (decoder_ == 0) return 1;
77
82
        if (!(filesize = FileSize(fn))) return -1;
78
83
        /* init decoder */
79
 
        if (!FLAC_plugin__decoder_init(decoder_, fn, filesize, &file_info_, &flac_cfg.output))
 
84
        if (!FLAC_plugin__decoder_init(decoder_, fn, filesize, &stream_data_, &flac_cfg.output))
80
85
                return 1;
81
86
        strcpy(lastfn_, fn);
82
87
        /* open output */
83
 
        maxlatency = mod_.outMod->Open(file_info_.sample_rate, file_info_.channels, file_info_.output_bits_per_sample, -1, -1);
 
88
        maxlatency = mod_.outMod->Open(stream_data_.sample_rate, stream_data_.channels, stream_data_.output_bits_per_sample, -1, -1);
84
89
        if (maxlatency < 0)
85
90
        {
86
91
                FLAC_plugin__decoder_finish(decoder_);
90
95
        mod_.outMod->SetVolume(-666);
91
96
        mod_.outMod->SetPan(0);
92
97
        /* initialize vis stuff */
93
 
        mod_.SAVSAInit(maxlatency, file_info_.sample_rate);
94
 
        mod_.VSASetInfo(file_info_.sample_rate, file_info_.channels);
 
98
        mod_.SAVSAInit(maxlatency, stream_data_.sample_rate);
 
99
        mod_.VSASetInfo(stream_data_.sample_rate, stream_data_.channels);
95
100
        /* set info */
96
 
        mod_.SetInfo(file_info_.average_bps, file_info_.sample_rate/1000, file_info_.channels, 1);
 
101
        mod_.SetInfo(stream_data_.average_bps, stream_data_.sample_rate/1000, stream_data_.channels, 1);
97
102
        /* start playing thread */
98
103
        paused = 0;
99
104
        thread_handle = CreateThread(NULL, 0, DecodeThread, NULL, 0, &thread_id);
106
111
{
107
112
        if (thread_handle)
108
113
        {
109
 
                file_info_.is_playing = false;
 
114
                stream_data_.is_playing = false;
110
115
                if (WaitForSingleObject(thread_handle, 2000) == WAIT_TIMEOUT)
111
116
                {
112
117
                        FLAC_plugin__show_error("Error while stopping decoding thread.");
144
149
 
145
150
static int getlength()
146
151
{
147
 
        return file_info_.length_in_msec;
 
152
        return stream_data_.length_in_msec;
148
153
}
149
154
 
150
155
static int getoutputtime()
154
159
 
155
160
static void setoutputtime(int time_in_ms)
156
161
{
157
 
        file_info_.seek_to = time_in_ms;
 
162
        stream_data_.seek_to = time_in_ms;
158
163
}
159
164
 
160
165
static void setvolume(int volume)
209
214
 
210
215
static DWORD WINAPI DecodeThread(void *unused)
211
216
{
212
 
        const unsigned channels = file_info_.channels;
213
 
        const unsigned bits_per_sample = file_info_.bits_per_sample;
214
 
        const unsigned target_bps = file_info_.output_bits_per_sample;
215
 
        const unsigned sample_rate = file_info_.sample_rate;
 
217
        const unsigned channels = stream_data_.channels;
 
218
        const unsigned bits_per_sample = stream_data_.bits_per_sample;
 
219
        const unsigned target_bps = stream_data_.output_bits_per_sample;
 
220
        const unsigned sample_rate = stream_data_.sample_rate;
216
221
        const unsigned fact = channels * (target_bps/8);
217
222
 
218
 
        while (file_info_.is_playing)
 
223
        while (stream_data_.is_playing)
219
224
        {
220
225
                /* seek needed */
221
 
                if (file_info_.seek_to != -1)
 
226
                if (stream_data_.seek_to != -1)
222
227
                {
223
 
                        const int pos = FLAC_plugin__seek(decoder_, &file_info_);
 
228
                        const int pos = FLAC_plugin__seek(decoder_, &stream_data_);
224
229
                        if (pos != -1) mod_.outMod->Flush(pos);
225
230
                }
226
231
                /* stream ended */
227
 
                else if (file_info_.eof)
 
232
                else if (stream_data_.eof)
228
233
                {
229
234
                        if (!mod_.outMod->IsPlaying())
230
235
                        {
237
242
                else
238
243
                {
239
244
                        /* decode samples */
240
 
                        int bytes = FLAC_plugin__decode(decoder_, &file_info_, sample_buffer_);
 
245
                        int bytes = FLAC_plugin__decode(decoder_, &stream_data_, sample_buffer_);
241
246
                        const int n = bytes / fact;
242
247
                        /* visualization */
243
248
                        do_vis(sample_buffer_, channels, target_bps, mod_.outMod->GetWrittenTime(), n);
245
250
                        if (mod_.dsp_isactive())
246
251
                                bytes = mod_.dsp_dosamples((short*)sample_buffer_, n, target_bps, channels, sample_rate) * fact;
247
252
                        /* output */
248
 
                        while (mod_.outMod->CanWrite()<bytes && file_info_.is_playing && file_info_.seek_to==-1)
 
253
                        while (mod_.outMod->CanWrite()<bytes && stream_data_.is_playing && stream_data_.seek_to==-1)
249
254
                                Sleep(20);
250
 
                        if (file_info_.is_playing && file_info_.seek_to==-1)
 
255
                        if (stream_data_.is_playing && stream_data_.seek_to==-1)
251
256
                                mod_.outMod->Write(sample_buffer_, bytes);
252
257
                        /* show bitrate */
253
258
                        if (flac_cfg.display.show_bps)
254
259
                        {
255
 
                                const int rate = FLAC_plugin__get_rate(mod_.outMod->GetWrittenTime(), mod_.outMod->GetOutputTime(), &file_info_);
256
 
                                if (rate) mod_.SetInfo(rate/1000, file_info_.sample_rate/1000, file_info_.channels, 1);
 
260
                                const int rate = FLAC_plugin__get_rate(mod_.outMod->GetWrittenTime(), mod_.outMod->GetOutputTime(), &stream_data_);
 
261
                                if (rate) mod_.SetInfo(rate/1000, stream_data_.sample_rate/1000, stream_data_.channels, 1);
257
262
                        }
258
263
                }
259
264
        }
326
331
{
327
332
        FLAC__StreamMetadata streaminfo;
328
333
 
329
 
        if (!filename || !*filename)
330
 
        {
 
334
        if (!filename || !*filename) {
331
335
                filename = lastfn_;
332
 
                if (length_in_msec)
333
 
                {
334
 
                        *length_in_msec = (int)file_info_.length_in_msec;
335
 
                        length_in_msec  = 0;    /* force skip in following code */
 
336
                if (length_in_msec) {
 
337
                        *length_in_msec = stream_data_.length_in_msec;
 
338
                        length_in_msec = 0;    /* force skip in following code */
336
339
                }
337
340
        }
338
341
 
339
 
        if (!FLAC__metadata_get_streaminfo(filename, &streaminfo))
340
 
        {
 
342
        if (!FLAC__metadata_get_streaminfo(filename, &streaminfo)) {
341
343
                if (length_in_msec)
342
344
                        *length_in_msec = -1;
343
345
                return;
344
346
        }
345
347
 
346
 
        if (title)
347
 
        {
 
348
        if (title) {
348
349
                static WCHAR buffer[400];
349
350
                format_title(filename, buffer, 400);
350
351
                WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, buffer, -1, title, 400, NULL, NULL);
351
352
        }
352
353
 
353
 
        if (length_in_msec)
 
354
        if (length_in_msec) {
354
355
                /* with VC++ you have to spoon feed it the casting from uint64->int64->double */
355
 
                *length_in_msec = (int)((double)(FLAC__int64)streaminfo.data.stream_info.total_samples / (double)streaminfo.data.stream_info.sample_rate * 1000.0 + 0.5);
 
356
                FLAC__uint64 l = (FLAC__uint64)((double)(FLAC__int64)streaminfo.data.stream_info.total_samples / (double)streaminfo.data.stream_info.sample_rate * 1000.0 + 0.5);
 
357
                if (l > INT_MAX)
 
358
                        l = INT_MAX;
 
359
                *length_in_msec = (int)l;
 
360
        }
356
361
}
357
362
 
358
363
/*