Audacious  $Id:Doxyfile42802007-03-2104:39:00Znenolod$
output.c
Go to the documentation of this file.
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 }