37
37
#undef G_LOG_DOMAIN
38
38
#define G_LOG_DOMAIN "decoder"
40
void decoder_initialized(G_GNUC_UNUSED struct decoder * decoder,
41
const struct audio_format *audio_format,
42
bool seekable, float total_time)
41
decoder_initialized(struct decoder *decoder,
42
const struct audio_format *audio_format,
43
bool seekable, float total_time)
44
assert(dc.state == DECODE_STATE_START);
45
assert(dc.pipe != NULL);
45
struct decoder_control *dc = decoder->dc;
46
struct audio_format_string af_string;
48
assert(dc->state == DECODE_STATE_START);
49
assert(dc->pipe != NULL);
46
50
assert(decoder != NULL);
47
51
assert(decoder->stream_tag == NULL);
48
52
assert(decoder->decoder_tag == NULL);
51
55
assert(audio_format_defined(audio_format));
52
56
assert(audio_format_valid(audio_format));
54
dc.in_audio_format = *audio_format;
55
getOutputAudioFormat(audio_format, &dc.out_audio_format);
57
dc.seekable = seekable;
58
dc.total_time = total_time;
60
dc.state = DECODE_STATE_DECODE;
61
notify_signal(&pc.notify);
63
g_debug("audio_format=%u:%u:%u, seekable=%s",
64
dc.in_audio_format.sample_rate, dc.in_audio_format.bits,
65
dc.in_audio_format.channels,
58
dc->in_audio_format = *audio_format;
59
getOutputAudioFormat(audio_format, &dc->out_audio_format);
61
dc->seekable = seekable;
62
dc->total_time = total_time;
65
dc->state = DECODE_STATE_DECODE;
70
g_debug("audio_format=%s, seekable=%s",
71
audio_format_to_string(&dc->in_audio_format, &af_string),
66
72
seekable ? "true" : "false");
68
if (!audio_format_equals(&dc.in_audio_format, &dc.out_audio_format))
69
g_debug("converting to %u:%u:%u",
70
dc.out_audio_format.sample_rate,
71
dc.out_audio_format.bits,
72
dc.out_audio_format.channels);
75
char *decoder_get_uri(G_GNUC_UNUSED struct decoder *decoder)
77
assert(dc.pipe != NULL);
79
return song_get_uri(dc.current_song);
74
if (!audio_format_equals(&dc->in_audio_format,
75
&dc->out_audio_format))
76
g_debug("converting to %s",
77
audio_format_to_string(&dc->out_audio_format,
82
81
enum decoder_command decoder_get_command(G_GNUC_UNUSED struct decoder * decoder)
84
assert(dc.pipe != NULL);
83
const struct decoder_control *dc = decoder->dc;
85
assert(dc->pipe != NULL);
89
void decoder_command_finished(G_GNUC_UNUSED struct decoder * decoder)
91
decoder_command_finished(struct decoder *decoder)
91
assert(dc.command != DECODE_COMMAND_NONE);
92
assert(dc.command != DECODE_COMMAND_SEEK ||
93
dc.seek_error || decoder->seeking);
94
assert(dc.pipe != NULL);
93
struct decoder_control *dc = decoder->dc;
97
assert(dc->command != DECODE_COMMAND_NONE);
98
assert(dc->command != DECODE_COMMAND_SEEK ||
99
dc->seek_error || decoder->seeking);
100
assert(dc->pipe != NULL);
96
102
if (decoder->seeking) {
97
103
decoder->seeking = false;
99
105
/* delete frames from the old song position */
101
107
if (decoder->chunk != NULL) {
102
music_buffer_return(dc.buffer, decoder->chunk);
108
music_buffer_return(dc->buffer, decoder->chunk);
103
109
decoder->chunk = NULL;
106
music_pipe_clear(dc.pipe, dc.buffer);
112
music_pipe_clear(dc->pipe, dc->buffer);
114
decoder->timestamp = dc->seek_where;
109
dc.command = DECODE_COMMAND_NONE;
110
notify_signal(&pc.notify);
117
dc->command = DECODE_COMMAND_NONE;
120
player_lock_signal();
113
123
double decoder_seek_where(G_GNUC_UNUSED struct decoder * decoder)
115
assert(dc.command == DECODE_COMMAND_SEEK);
116
assert(dc.pipe != NULL);
125
const struct decoder_control *dc = decoder->dc;
127
assert(dc->command == DECODE_COMMAND_SEEK);
128
assert(dc->pipe != NULL);
118
130
decoder->seeking = true;
120
return dc.seek_where;
132
return dc->seek_where;
123
135
void decoder_seek_error(struct decoder * decoder)
125
assert(dc.command == DECODE_COMMAND_SEEK);
126
assert(dc.pipe != NULL);
128
dc.seek_error = true;
137
struct decoder_control *dc = decoder->dc;
139
assert(dc->command == DECODE_COMMAND_SEEK);
140
assert(dc->pipe != NULL);
142
dc->seek_error = true;
129
143
decoder->seeking = false;
131
145
decoder_command_finished(decoder);
135
149
struct input_stream *is,
136
150
void *buffer, size_t length)
152
const struct decoder_control *dc =
153
decoder != NULL ? decoder->dc : NULL;
154
GError *error = NULL;
140
157
assert(decoder == NULL ||
141
dc.state == DECODE_STATE_START ||
142
dc.state == DECODE_STATE_DECODE);
158
dc->state == DECODE_STATE_START ||
159
dc->state == DECODE_STATE_DECODE);
143
160
assert(is != NULL);
144
161
assert(buffer != NULL);
152
169
/* ignore the SEEK command during initialization,
153
170
the plugin should handle that after it has
154
171
initialized successfully */
155
(dc.command != DECODE_COMMAND_SEEK ||
156
(dc.state != DECODE_STATE_START && !decoder->seeking)) &&
157
dc.command != DECODE_COMMAND_NONE)
160
nbytes = input_stream_read(is, buffer, length);
172
(dc->command != DECODE_COMMAND_SEEK ||
173
(dc->state != DECODE_STATE_START && !decoder->seeking)) &&
174
dc->command != DECODE_COMMAND_NONE)
177
nbytes = input_stream_read(is, buffer, length, &error);
179
if (G_UNLIKELY(nbytes == 0 && error != NULL)) {
180
g_warning("%s", error->message);
161
185
if (nbytes > 0 || input_stream_eof(is))
181
214
/* there is a partial chunk - flush it, we want the
182
215
tag in a new chunk */
183
216
decoder_flush_chunk(decoder);
184
notify_signal(&pc.notify);
217
player_lock_signal();
187
220
assert(decoder->chunk == NULL);
189
222
chunk = decoder_get_chunk(decoder, is);
190
223
if (chunk == NULL) {
191
assert(dc.command != DECODE_COMMAND_NONE);
224
assert(decoder->dc->command != DECODE_COMMAND_NONE);
225
return decoder->dc->command;
195
228
chunk->tag = tag_dup(tag);
225
258
decoder_data(struct decoder *decoder,
226
259
struct input_stream *is,
227
260
const void *_data, size_t length,
228
float data_time, uint16_t bitRate,
229
struct replay_gain_info *replay_gain_info)
263
struct decoder_control *dc = decoder->dc;
231
264
const char *data = _data;
233
assert(dc.state == DECODE_STATE_DECODE);
234
assert(dc.pipe != NULL);
235
assert(length % audio_format_frame_size(&dc.in_audio_format) == 0);
237
if (dc.command == DECODE_COMMAND_STOP ||
238
dc.command == DECODE_COMMAND_SEEK ||
265
GError *error = NULL;
266
enum decoder_command cmd;
268
assert(dc->state == DECODE_STATE_DECODE);
269
assert(dc->pipe != NULL);
270
assert(length % audio_format_frame_size(&dc->in_audio_format) == 0);
276
if (cmd == DECODE_COMMAND_STOP || cmd == DECODE_COMMAND_SEEK ||
242
280
/* send stream tags */
244
282
if (update_stream_tag(decoder, is)) {
245
enum decoder_command cmd;
247
283
if (decoder->decoder_tag != NULL) {
248
284
/* merge with tag from decoder plugin */
251
tag = tag_merge(decoder->stream_tag,
252
decoder->decoder_tag);
287
tag = tag_merge(decoder->decoder_tag,
288
decoder->stream_tag);
253
289
cmd = do_send_tag(decoder, is, tag);
263
if (!audio_format_equals(&dc.in_audio_format, &dc.out_audio_format)) {
299
if (!audio_format_equals(&dc->in_audio_format, &dc->out_audio_format)) {
264
300
data = pcm_convert(&decoder->conv_state,
265
&dc.in_audio_format, data, length,
266
&dc.out_audio_format, &length);
268
/* under certain circumstances, pcm_convert() may
269
return an empty buffer - this condition should be
270
investigated further, but for now, do this check as
273
return DECODE_COMMAND_NONE;
301
&dc->in_audio_format, data, length,
302
&dc->out_audio_format, &length,
305
/* the PCM conversion has failed - stop
306
playback, since we have no better way to
308
g_warning("%s", error->message);
309
return DECODE_COMMAND_STOP;
276
313
while (length > 0) {
282
319
chunk = decoder_get_chunk(decoder, is);
283
320
if (chunk == NULL) {
284
assert(dc.command != DECODE_COMMAND_NONE);
321
assert(dc->command != DECODE_COMMAND_NONE);
288
dest = music_chunk_write(chunk, &dc.out_audio_format,
289
data_time, bitRate, &nbytes);
325
dest = music_chunk_write(chunk, &dc->out_audio_format,
327
dc->song->start_ms / 1000.0,
290
329
if (dest == NULL) {
291
330
/* the chunk is full, flush it */
292
331
decoder_flush_chunk(decoder);
293
notify_signal(&pc.notify);
332
player_lock_signal();
304
343
memcpy(dest, data, nbytes);
306
/* apply replay gain or normalization */
308
if (replay_gain_info != NULL &&
309
replay_gain_mode != REPLAY_GAIN_OFF)
310
replay_gain_apply(replay_gain_info, dest, nbytes,
311
&dc.out_audio_format);
312
else if (normalizationEnabled)
313
normalizeData(dest, nbytes, &dc.out_audio_format);
315
345
/* expand the music pipe chunk */
317
full = music_chunk_expand(chunk, &dc.out_audio_format, nbytes);
347
full = music_chunk_expand(chunk, &dc->out_audio_format, nbytes);
319
349
/* the chunk is full, flush it */
320
350
decoder_flush_chunk(decoder);
321
notify_signal(&pc.notify);
351
player_lock_signal();
325
355
length -= nbytes;
357
decoder->timestamp += (double)nbytes /
358
audio_format_time_to_size(&dc->out_audio_format);
360
if (dc->song->end_ms > 0 &&
361
decoder->timestamp >= dc->song->end_ms / 1000.0)
362
/* the end of this range has been reached:
364
return DECODE_COMMAND_STOP;
328
367
return DECODE_COMMAND_NONE;
332
371
decoder_tag(G_GNUC_UNUSED struct decoder *decoder, struct input_stream *is,
333
372
const struct tag *tag)
374
G_GNUC_UNUSED const struct decoder_control *dc = decoder->dc;
335
375
enum decoder_command cmd;
337
assert(dc.state == DECODE_STATE_DECODE);
338
assert(dc.pipe != NULL);
377
assert(dc->state == DECODE_STATE_DECODE);
378
assert(dc->pipe != NULL);
339
379
assert(tag != NULL);
341
381
/* save the tag */
408
decoder_replay_gain(struct decoder *decoder,
409
const struct replay_gain_info *replay_gain_info)
412
assert(decoder != NULL);
414
if (replay_gain_info != NULL) {
415
static unsigned serial;
419
if (REPLAY_GAIN_OFF != replay_gain_mode) {
420
return_db = 20.0 * log10f(
421
replay_gain_tuple_scale(
422
&replay_gain_info->tuples[replay_gain_get_real_mode()],
423
replay_gain_preamp, replay_gain_missing_preamp,
427
decoder->replay_gain_info = *replay_gain_info;
428
decoder->replay_gain_serial = serial;
430
if (decoder->chunk != NULL) {
431
/* flush the current chunk because the new
432
replay gain values affect the following
434
decoder_flush_chunk(decoder);
435
player_lock_signal();
438
decoder->replay_gain_serial = 0;
444
decoder_mixramp(struct decoder *decoder, float replay_gain_db,
445
char *mixramp_start, char *mixramp_end)
447
assert(decoder != NULL);
448
struct decoder_control *dc = decoder->dc;
451
dc->replay_gain_db = replay_gain_db;
452
dc_mixramp_start(dc, mixramp_start);
453
dc_mixramp_end(dc, mixramp_end);