Audacious $Id:Doxyfile42802007-03-2104:39:00Znenolod$
|
00001 /* 00002 * output.c 00003 * Copyright 2009-2010 John Lindgren 00004 * 00005 * This file is part of Audacious. 00006 * 00007 * Audacious is free software: you can redistribute it and/or modify it under 00008 * the terms of the GNU General Public License as published by the Free Software 00009 * Foundation, version 2 or version 3 of the License. 00010 * 00011 * Audacious is distributed in the hope that it will be useful, but WITHOUT ANY 00012 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00013 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along with 00016 * Audacious. If not, see <http://www.gnu.org/licenses/>. 00017 * 00018 * The Audacious team does not consider modular code linking to Audacious or 00019 * using our public API to be a derived work. 00020 */ 00021 00022 #include <glib.h> 00023 #include <math.h> 00024 #include <pthread.h> 00025 #include <string.h> 00026 00027 #include "debug.h" 00028 #include "effect.h" 00029 #include "equalizer.h" 00030 #include "misc.h" 00031 #include "output.h" 00032 #include "playback.h" 00033 #include "plugins.h" 00034 #include "vis_runner.h" 00035 00036 #define SW_VOLUME_RANGE 40 /* decibels */ 00037 00038 static OutputPlugin * cop = NULL; 00039 00040 void output_get_volume (int * l, int * r) 00041 { 00042 if (get_bool (NULL, "software_volume_control")) 00043 { 00044 * l = get_int (NULL, "sw_volume_left"); 00045 * r = get_int (NULL, "sw_volume_right"); 00046 } 00047 else if (cop != NULL && cop->get_volume != NULL) 00048 cop->get_volume (l, r); 00049 else 00050 { 00051 * l = 0; 00052 * r = 0; 00053 } 00054 } 00055 00056 void output_set_volume (int l, int r) 00057 { 00058 if (get_bool (NULL, "software_volume_control")) 00059 { 00060 set_int (NULL, "sw_volume_left", l); 00061 set_int (NULL, "sw_volume_right", r); 00062 } 00063 else if (cop != NULL && cop->set_volume != NULL) 00064 cop->set_volume (l, r); 00065 } 00066 00067 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 00068 static bool_t locked = FALSE; 00069 00070 #define LOCK do {pthread_mutex_lock (& mutex); locked = TRUE;} while (0) 00071 #define UNLOCK do {locked = FALSE; pthread_mutex_unlock (& mutex);} while (0) 00072 #define LOCKED g_return_if_fail (locked) 00073 #define LOCKED_RET(a) g_return_val_if_fail (locked, a) 00074 #define LOCK_VIS do {vis_runner_lock (); LOCK;} while (0) 00075 #define UNLOCK_VIS do {UNLOCK; vis_runner_unlock ();} while (0) 00076 #define LOCKED_VIS g_return_if_fail (locked && vis_runner_locked ()) 00077 #define LOCKED_VIS_RET(a) g_return_val_if_fail (locked && vis_runner_locked (), a) 00078 00079 static bool_t opened = FALSE; 00080 static bool_t leave_open = FALSE; 00081 00082 static bool_t waiting, aborted, paused; 00083 static int decoder_format, decoder_channels, decoder_rate, effect_channels, 00084 effect_rate, output_format, output_channels, output_rate; 00085 static int64_t frames_written; 00086 static bool_t have_replay_gain; 00087 static ReplayGainInfo replay_gain_info; 00088 00089 static void reset_time (void) 00090 { 00091 LOCKED_VIS; 00092 g_return_if_fail (cop->set_written_time != NULL); 00093 vis_runner_time_offset (- cop->written_time ()); 00094 cop->set_written_time (0); 00095 } 00096 00097 static void drain (void) 00098 { 00099 LOCKED; 00100 g_return_if_fail (cop->drain != NULL); 00101 cop->drain (); 00102 } 00103 00104 static void real_close (void) 00105 { 00106 LOCKED_VIS; 00107 vis_runner_start_stop (FALSE, FALSE); 00108 cop->close_audio (); 00109 opened = FALSE; 00110 leave_open = FALSE; 00111 } 00112 00113 static bool_t open_audio (int format, int rate, int channels) 00114 { 00115 LOCKED_VIS_RET (FALSE); 00116 g_return_val_if_fail (! opened, FALSE); 00117 00118 decoder_format = format; 00119 decoder_channels = channels; 00120 decoder_rate = rate; 00121 effect_channels = channels; 00122 effect_rate = rate; 00123 effect_start (& effect_channels, & effect_rate); 00124 eq_set_format (effect_channels, effect_rate); 00125 00126 if (leave_open && effect_channels == output_channels && effect_rate == 00127 output_rate) 00128 { 00129 reset_time (); 00130 opened = TRUE; 00131 } 00132 else 00133 { 00134 if (leave_open) 00135 { 00136 drain (); 00137 real_close (); 00138 } 00139 00140 int depth = get_int (NULL, "output_bit_depth"); 00141 output_format = (depth == 32) ? FMT_S32_NE : (depth == 24) ? FMT_S24_NE 00142 : (depth == 16) ? FMT_S16_NE : FMT_FLOAT; 00143 output_channels = effect_channels; 00144 output_rate = effect_rate; 00145 00146 if (cop->open_audio (output_format, output_rate, output_channels)) 00147 { 00148 vis_runner_start_stop (TRUE, FALSE); 00149 opened = TRUE; 00150 } 00151 } 00152 00153 leave_open = FALSE; 00154 waiting = FALSE; 00155 aborted = FALSE; 00156 paused = FALSE; 00157 frames_written = 0; 00158 have_replay_gain = FALSE; 00159 00160 return opened; 00161 } 00162 00163 static bool_t output_open_audio (int format, int rate, int channels) 00164 { 00165 g_return_val_if_fail (cop != NULL, FALSE); 00166 LOCK_VIS; 00167 bool_t success = open_audio (format, rate, channels); 00168 UNLOCK_VIS; 00169 return success; 00170 } 00171 00172 static void set_gain (ReplayGainInfo * info) 00173 { 00174 LOCKED; 00175 g_return_if_fail (opened && ! waiting); 00176 00177 AUDDBG ("Replay Gain info:\n"); 00178 AUDDBG (" album gain: %f dB\n", info->album_gain); 00179 AUDDBG (" album peak: %f\n", info->album_peak); 00180 AUDDBG (" track gain: %f dB\n", info->track_gain); 00181 AUDDBG (" track peak: %f\n", info->track_peak); 00182 00183 have_replay_gain = TRUE; 00184 memcpy (& replay_gain_info, info, sizeof (ReplayGainInfo)); 00185 } 00186 00187 static void output_set_replaygain_info (ReplayGainInfo * info) 00188 { 00189 g_return_if_fail (cop != NULL); 00190 LOCK; 00191 set_gain (info); 00192 UNLOCK; 00193 } 00194 00195 static void apply_replay_gain (float * data, int samples) 00196 { 00197 if (! get_bool (NULL, "enable_replay_gain")) 00198 return; 00199 00200 float factor = powf (10, get_double (NULL, "replay_gain_preamp") / 20); 00201 00202 if (have_replay_gain) 00203 { 00204 if (get_bool (NULL, "replay_gain_album")) 00205 { 00206 factor *= powf (10, replay_gain_info.album_gain / 20); 00207 00208 if (get_bool (NULL, "enable_clipping_prevention") && 00209 replay_gain_info.album_peak * factor > 1) 00210 factor = 1 / replay_gain_info.album_peak; 00211 } 00212 else 00213 { 00214 factor *= powf (10, replay_gain_info.track_gain / 20); 00215 00216 if (get_bool (NULL, "enable_clipping_prevention") && 00217 replay_gain_info.track_peak * factor > 1) 00218 factor = 1 / replay_gain_info.track_peak; 00219 } 00220 } 00221 else 00222 factor *= powf (10, get_double (NULL, "default_gain") / 20); 00223 00224 if (factor < 0.99 || factor > 1.01) 00225 audio_amplify (data, 1, samples, & factor); 00226 } 00227 00228 static void apply_software_volume (float * data, int channels, int frames) 00229 { 00230 float left_factor, right_factor; 00231 float factors[channels]; 00232 int channel; 00233 00234 if (! get_bool (NULL, "software_volume_control")) 00235 return; 00236 00237 int l = get_int (NULL, "sw_volume_left"); 00238 int r = get_int (NULL, "sw_volume_right"); 00239 if (l == 100 && r == 100) 00240 return; 00241 00242 left_factor = (l == 0) ? 0 : powf (10, (float) SW_VOLUME_RANGE * (l - 100) / 100 / 20); 00243 right_factor = (r == 0) ? 0 : powf (10, (float) SW_VOLUME_RANGE * (r - 100) / 100 / 20); 00244 00245 if (channels == 2) 00246 { 00247 factors[0] = left_factor; 00248 factors[1] = right_factor; 00249 } 00250 else 00251 { 00252 for (channel = 0; channel < channels; channel ++) 00253 factors[channel] = MAX (left_factor, right_factor); 00254 } 00255 00256 audio_amplify (data, channels, frames, factors); 00257 } 00258 00259 static void write_processed (void * data, int samples) 00260 { 00261 LOCKED_VIS; 00262 00263 if (! samples) 00264 return; 00265 00266 vis_runner_pass_audio (cop->written_time (), data, samples, output_channels, 00267 output_rate); 00268 eq_filter (data, samples); 00269 apply_software_volume (data, output_channels, samples / output_channels); 00270 00271 void * allocated = NULL; 00272 00273 if (output_format != FMT_FLOAT) 00274 { 00275 void * new = g_malloc (FMT_SIZEOF (output_format) * samples); 00276 audio_to_int (data, new, output_format, samples); 00277 data = new; 00278 g_free (allocated); 00279 allocated = new; 00280 } 00281 00282 while (! aborted) 00283 { 00284 int ready = (cop->buffer_free != NULL) ? cop->buffer_free () / 00285 FMT_SIZEOF (output_format) : output_channels * (output_rate / 50); 00286 ready = MIN (ready, samples); 00287 cop->write_audio (data, FMT_SIZEOF (output_format) * ready); 00288 data = (char *) data + FMT_SIZEOF (output_format) * ready; 00289 samples -= ready; 00290 00291 if (! samples) 00292 break; 00293 00294 waiting = TRUE; 00295 UNLOCK_VIS; 00296 00297 if (cop->period_wait != NULL) 00298 cop->period_wait (); 00299 else if (cop->buffer_free != NULL) 00300 g_usleep (20000); 00301 00302 LOCK_VIS; 00303 waiting = FALSE; 00304 } 00305 00306 g_free (allocated); 00307 } 00308 00309 static void write_audio (void * data, int size) 00310 { 00311 LOCKED; 00312 g_return_if_fail (opened && ! waiting); 00313 00314 int samples = size / FMT_SIZEOF (decoder_format); 00315 frames_written += samples / decoder_channels; 00316 00317 void * allocated = NULL; 00318 00319 if (decoder_format != FMT_FLOAT) 00320 { 00321 float * new = g_malloc (sizeof (float) * samples); 00322 audio_from_int (data, decoder_format, new, samples); 00323 data = new; 00324 g_free (allocated); 00325 allocated = new; 00326 } 00327 00328 apply_replay_gain (data, samples); 00329 float * fdata = data; 00330 effect_process (& fdata, & samples); 00331 data = fdata; 00332 00333 if (data != allocated) 00334 { 00335 g_free (allocated); 00336 allocated = NULL; 00337 } 00338 00339 write_processed (data, samples); 00340 g_free (allocated); 00341 } 00342 00343 static void output_write_audio (void * data, int size) 00344 { 00345 g_return_if_fail (cop != NULL); 00346 LOCK_VIS; 00347 write_audio (data, size); 00348 UNLOCK_VIS; 00349 } 00350 00351 static void close_audio (void) 00352 { 00353 LOCKED; 00354 g_return_if_fail (opened && ! waiting); 00355 opened = FALSE; 00356 00357 if (! leave_open) 00358 { 00359 effect_flush (); 00360 real_close (); 00361 } 00362 } 00363 00364 static void output_close_audio (void) 00365 { 00366 g_return_if_fail (cop != NULL); 00367 LOCK_VIS; 00368 close_audio (); 00369 UNLOCK_VIS; 00370 } 00371 00372 static void do_pause (bool_t p) 00373 { 00374 LOCKED_VIS; 00375 g_return_if_fail (opened); 00376 cop->pause (p); 00377 vis_runner_start_stop (TRUE, p); 00378 paused = p; 00379 } 00380 00381 static void output_pause (bool_t p) 00382 { 00383 g_return_if_fail (cop != NULL); 00384 LOCK_VIS; 00385 do_pause (p); 00386 UNLOCK_VIS; 00387 } 00388 00389 static void flush (int time) 00390 { 00391 LOCKED_VIS; 00392 g_return_if_fail (opened); 00393 00394 aborted = FALSE; 00395 00396 /* When playback is started from the middle of a song, flush() is called 00397 * before any audio is actually written in order to set the time counter. 00398 * In this case, we do not want to cut off the end of the previous song, so 00399 * we do not actually flush. */ 00400 if (! frames_written) 00401 { 00402 g_return_if_fail (cop->set_written_time != NULL); 00403 vis_runner_time_offset (time - cop->written_time ()); 00404 cop->set_written_time (time); 00405 } 00406 else 00407 { 00408 vis_runner_flush (); 00409 effect_flush (); 00410 cop->flush (effect_decoder_to_output_time (time)); 00411 } 00412 00413 frames_written = time * (int64_t) decoder_rate / 1000; 00414 } 00415 00416 static void output_flush (int time) 00417 { 00418 g_return_if_fail (cop != NULL); 00419 LOCK_VIS; 00420 flush (time); 00421 UNLOCK_VIS; 00422 } 00423 00424 static int written_time (void) 00425 { 00426 LOCKED_RET (0); 00427 g_return_val_if_fail (opened && ! waiting, 0); 00428 return frames_written * (int64_t) 1000 / decoder_rate; 00429 } 00430 00431 static int output_written_time (void) 00432 { 00433 g_return_val_if_fail (cop != NULL, 0); 00434 LOCK; 00435 int time = written_time (); 00436 UNLOCK; 00437 return time; 00438 } 00439 00440 static void write_buffers (void) 00441 { 00442 LOCKED; 00443 float * data = NULL; 00444 int samples = 0; 00445 effect_finish (& data, & samples); 00446 write_processed (data, samples); 00447 } 00448 00449 static void set_leave_open (void) 00450 { 00451 LOCKED; 00452 g_return_if_fail (opened && ! waiting); 00453 00454 if (! paused) 00455 { 00456 write_buffers (); 00457 leave_open = TRUE; 00458 } 00459 } 00460 00461 static bool_t output_buffer_playing (void) 00462 { 00463 g_return_val_if_fail (cop != NULL, FALSE); 00464 LOCK_VIS; 00465 set_leave_open (); 00466 UNLOCK_VIS; 00467 return FALSE; 00468 } 00469 00470 static void abort_write (void) 00471 { 00472 LOCKED; 00473 g_return_if_fail (opened); 00474 aborted = TRUE; 00475 cop->flush (cop->output_time ()); 00476 } 00477 00478 static void output_abort_write (void) 00479 { 00480 g_return_if_fail (cop != NULL); 00481 LOCK; 00482 abort_write (); 00483 UNLOCK; 00484 } 00485 00486 const struct OutputAPI output_api = 00487 { 00488 .open_audio = output_open_audio, 00489 .set_replaygain_info = output_set_replaygain_info, 00490 .write_audio = output_write_audio, 00491 .close_audio = output_close_audio, 00492 00493 .pause = output_pause, 00494 .flush = output_flush, 00495 .written_time = output_written_time, 00496 .buffer_playing = output_buffer_playing, 00497 .abort_write = output_abort_write, 00498 }; 00499 00500 static int output_time (void) 00501 { 00502 LOCKED_RET (0); 00503 g_return_val_if_fail (opened || leave_open, 0); 00504 return cop->output_time (); 00505 } 00506 00507 int get_output_time (void) 00508 { 00509 g_return_val_if_fail (cop != NULL, 0); 00510 LOCK; 00511 00512 int time = 0; 00513 if (opened) 00514 { 00515 time = effect_output_to_decoder_time (output_time ()); 00516 time = MAX (0, time); 00517 } 00518 00519 UNLOCK; 00520 return time; 00521 } 00522 00523 int get_raw_output_time (void) 00524 { 00525 g_return_val_if_fail (cop != NULL, 0); 00526 LOCK; 00527 int time = output_time (); 00528 UNLOCK; 00529 return time; 00530 } 00531 00532 void output_drain (void) 00533 { 00534 g_return_if_fail (cop != NULL); 00535 LOCK_VIS; 00536 00537 if (leave_open) 00538 { 00539 write_buffers (); 00540 drain (); 00541 real_close (); 00542 } 00543 00544 UNLOCK_VIS; 00545 } 00546 00547 static bool_t probe_cb (PluginHandle * p, PluginHandle * * pp) 00548 { 00549 OutputPlugin * op = plugin_get_header (p); 00550 g_return_val_if_fail (op != NULL && op->init != NULL, TRUE); 00551 00552 if (! op->init ()) 00553 return TRUE; 00554 00555 if (op->cleanup != NULL) 00556 op->cleanup (); 00557 00558 * pp = p; 00559 return FALSE; 00560 } 00561 00562 PluginHandle * output_plugin_probe (void) 00563 { 00564 PluginHandle * p = NULL; 00565 plugin_for_each (PLUGIN_TYPE_OUTPUT, (PluginForEachFunc) probe_cb, & p); 00566 return p; 00567 } 00568 00569 PluginHandle * output_plugin_get_current (void) 00570 { 00571 return (cop != NULL) ? plugin_by_header (cop) : NULL; 00572 } 00573 00574 bool_t output_plugin_set_current (PluginHandle * plugin) 00575 { 00576 if (cop != NULL) 00577 { 00578 if (playback_get_playing ()) 00579 playback_stop (); 00580 00581 if (cop->cleanup != NULL) 00582 cop->cleanup (); 00583 00584 cop = NULL; 00585 } 00586 00587 if (plugin != NULL) 00588 { 00589 OutputPlugin * op = plugin_get_header (plugin); 00590 g_return_val_if_fail (op != NULL && op->init != NULL, FALSE); 00591 00592 if (! op->init ()) 00593 return FALSE; 00594 00595 cop = op; 00596 } 00597 00598 return TRUE; 00599 }