00001 #ifndef AUDIOOUTPUTBASE
00002 #define AUDIOOUTPUTBASE
00003
00004
00005 #include <sys/time.h>
00006
00007
00008 #include <iostream>
00009 using namespace std;
00010
00011
00012 #include <QString>
00013 #include <QMutex>
00014 #include <QWaitCondition>
00015
00016
00017 #include "audiooutput.h"
00018 #include "samplerate.h"
00019 #include "mythlogging.h"
00020 #include "mthread.h"
00021
00022 #define VBAUDIO(str) LOG(VB_AUDIO, LOG_INFO, LOC + str)
00023 #define VBAUDIOTS(str) LOG(VB_AUDIO | VB_TIMESTAMP, LOG_INFO, LOC + str)
00024 #define VBGENERAL(str) LOG(VB_GENERAL, LOG_INFO, LOC + str)
00025 #define VBERROR(str) LOG(VB_GENERAL, LOG_ERR, LOC + str)
00026 #define VBWARN(str) LOG(VB_GENERAL, LOG_WARNING, LOC + str)
00027 #define VBERRENO(str) Error(LOC + str + ": " + ENO)
00028
00029 namespace soundtouch {
00030 class SoundTouch;
00031 };
00032 class FreeSurround;
00033 class AudioOutputDigitalEncoder;
00034 struct AVCodecContext;
00035
00036 class AsyncLooseLock
00037 {
00038 public:
00039 AsyncLooseLock() { head = tail = 0; }
00040 void Clear() { head = tail = 0; }
00041 void Ref() { head++; }
00042 bool TestAndDeref() { bool r; if ((r=(head != tail))) tail++; return r; }
00043 private:
00044 int head;
00045 int tail;
00046 };
00047
00048
00049 class SPDIFEncoder;
00050
00051 class AudioOutputBase : public AudioOutput, public MThread
00052 {
00053 public:
00054 const char *quality_string(int q);
00055 AudioOutputBase(const AudioSettings &settings);
00056 virtual ~AudioOutputBase();
00057
00058 AudioOutputSettings* GetOutputSettingsCleaned(bool digital = true);
00059 AudioOutputSettings* GetOutputSettingsUsers(bool digital = false);
00060
00061
00062 virtual void Reconfigure(const AudioSettings &settings);
00063
00064
00065 virtual void SetEffDsp(int dsprate);
00066
00067
00068 virtual void SetStretchFactor(float factor);
00069 virtual float GetStretchFactor(void) const;
00070 virtual int GetChannels(void) const { return channels; }
00071 virtual AudioFormat GetFormat(void) const { return format; };
00072 virtual int GetBytesPerFrame(void) const { return source_bytes_per_frame; };
00073
00074 virtual bool CanPassthrough(int samplerate, int channels,
00075 int codec, int profile) const;
00076 virtual bool CanDownmix(void) const { return true; };
00077 virtual bool IsUpmixing(void);
00078 virtual bool ToggleUpmix(void);
00079 virtual bool CanUpmix(void);
00080
00081 virtual void Reset(void);
00082
00083 void SetSWVolume(int new_volume, bool save);
00084 int GetSWVolume(void);
00085
00086
00087 virtual bool AddFrames(void *buffer, int frames, int64_t timecode);
00088 virtual bool AddData(void *buffer, int len, int64_t timecode, int frames);
00089 virtual bool NeedDecodingBeforePassthrough() const { return false; };
00090 virtual int64_t LengthLastData(void) const { return m_length_last_data; }
00091
00092 virtual void SetTimecode(int64_t timecode);
00093 virtual bool IsPaused(void) const { return actually_paused; }
00094 virtual void Pause(bool paused);
00095 void PauseUntilBuffered(void);
00096
00097
00098 virtual void Drain(void);
00099
00100 virtual int64_t GetAudiotime(void);
00101 virtual int64_t GetAudioBufferedTime(void);
00102
00103
00104 virtual void Status(void);
00105
00106 virtual void SetSourceBitrate(int rate);
00107
00108 virtual void GetBufferStatus(uint &fill, uint &total);
00109
00110
00111 virtual void bufferOutputData(bool y){ buffer_output_data_for_use = y; }
00112 virtual int readOutputData(unsigned char *read_buffer, int max_length);
00113
00114 static const uint kAudioSRCInputSize = 16384;
00115
00117 static const uint kAudioRingBufferSize = 3072000u;
00118
00119 protected:
00120
00121 void InitSettings(const AudioSettings &settings);
00122
00123
00124 virtual bool OpenDevice(void) = 0;
00125 virtual void CloseDevice(void) = 0;
00126 virtual void WriteAudio(uchar *aubuf, int size) = 0;
00131 virtual int GetBufferedOnSoundcard(void) const = 0;
00132
00133 virtual AudioOutputSettings* GetOutputSettings(bool digital)
00134 { return new AudioOutputSettings; }
00135
00136 void KillAudio(void);
00137
00138
00139 virtual bool StartOutputThread(void);
00140 virtual void StopOutputThread(void);
00141
00142 int GetAudioData(uchar *buffer, int buf_size, bool fill_buffer,
00143 volatile uint *local_raud = NULL);
00144
00145 void OutputAudioLoop(void);
00146
00147 virtual void run();
00148
00149 int CheckFreeSpace(int &frames);
00150
00151 inline int audiolen();
00152 int audiofree();
00153 int audioready();
00154
00155 void SetStretchFactorLocked(float factor);
00156
00157
00158 int GetBaseAudBufTimeCode() const { return audbuf_timecode; }
00159
00160 protected:
00161
00162 int channels;
00163 int codec;
00164 int bytes_per_frame;
00165 int output_bytes_per_frame;
00166 AudioFormat format;
00167 AudioFormat output_format;
00168 int samplerate;
00169
00170 int effdsp;
00171 int fragment_size;
00172 long soundcard_buffer_size;
00173
00174 QString main_device, passthru_device;
00175 bool m_discretedigital;
00176
00177 bool passthru, enc, reenc;
00178
00179 float stretchfactor;
00180 int eff_stretchfactor;
00181 AudioOutputSource source;
00182
00183 bool killaudio;
00184
00185 bool pauseaudio, actually_paused, was_paused, unpause_when_ready;
00186 bool set_initial_vol;
00187 bool buffer_output_data_for_use;
00188
00189 int configured_channels;
00190 int max_channels;
00191 enum
00192 {
00193 QUALITY_DISABLED = -1,
00194 QUALITY_LOW = 0,
00195 QUALITY_MEDIUM = 1,
00196 QUALITY_HIGH = 2,
00197 };
00198 int src_quality;
00199
00200 private:
00201 bool SetupPassthrough(int codec, int codec_profile,
00202 int &samplerate_tmp, int &channels_tmp);
00203 AudioOutputSettings* OutputSettings(bool digital = true);
00204 int CopyWithUpmix(char *buffer, int frames, uint &org_waud);
00205 void SetAudiotime(int frames, int64_t timecode);
00206 AudioOutputSettings *output_settingsraw;
00207 AudioOutputSettings *output_settings;
00208 AudioOutputSettings *output_settingsdigitalraw;
00209 AudioOutputSettings *output_settingsdigital;
00210 bool need_resampler;
00211 SRC_STATE *src_ctx;
00212 soundtouch::SoundTouch *pSoundStretch;
00213 AudioOutputDigitalEncoder *encoder;
00214 FreeSurround *upmixer;
00215
00216 int source_channels;
00217 int source_samplerate;
00218 int source_bytes_per_frame;
00219 bool upmix_default;
00220 bool needs_upmix;
00221 bool needs_downmix;
00222 int surround_mode;
00223 float old_stretchfactor;
00224 int volume;
00225 QString volumeControl;
00226
00227 bool processing;
00228
00229 int64_t frames_buffered;
00230
00231 bool audio_thread_exists;
00232
00237 QMutex audio_buflock;
00238
00243 QMutex avsync_lock;
00244
00248 int64_t audiotime;
00249
00253 volatile uint raud, waud;
00257 int64_t audbuf_timecode;
00258 AsyncLooseLock reset_active;
00259
00260 QMutex killAudioLock;
00261
00262 long current_seconds;
00263 long source_bitrate;
00264
00265 float *src_in;
00266
00267
00268 SRC_DATA src_data;
00269 uint memory_corruption_test0;
00270 float src_in_buf[kAudioSRCInputSize + 16];
00271 uint memory_corruption_test1;
00272 float *src_out;
00273 int kAudioSRCOutputSize;
00274 uint memory_corruption_test2;
00278 uchar audiobuffer[kAudioRingBufferSize];
00279 uint memory_corruption_test3;
00280 uint m_configure_succeeded;
00281 int64_t m_length_last_data;
00282
00283
00284 SPDIFEncoder *m_spdifenc;
00285
00286
00287 bool m_forcedprocessing;
00288 int m_previousbpf;
00289 };
00290
00291 #endif