Ticket #8500: accurate_audiots.3.patch

File accurate_audiots.3.patch, 24.0 KB (added by Mark Spieth, 9 years ago)

with timecode wrap fix

  • mythtv/libs/libmyth/audiooutput.h

    commit adc6deaaee787ec55bd2303b542b93f64d992515
    Author: Mark Spieth <mspieth@digivation.com.au>
    Date:   Tue Apr 27 07:51:51 2010 +1000
    
        smoother vsync with predictive frame skipping
    
    diff --git a/mythtv/libs/libmyth/audiooutput.h b/mythtv/libs/libmyth/audiooutput.h
    index 8947981..4fe5b8f 100644
    a b  
    33
    44#include <QString>
    55
     6#include "compat.h"
    67#include "audiosettings.h"
    78#include "mythcorecontext.h"
    89#include "volumebase.h"
    class MPUBLIC AudioOutput : public VolumeBase, public OutputListeners 
    4142
    4243    virtual void Reset(void) = 0;
    4344
    44     virtual bool AddSamples(void *buffer, int samples, long long timecode) = 0;
     45    virtual bool AddSamples(void *buffer, int samples, int64_t timecode) = 0;
    4546
    46     virtual void SetTimecode(long long timecode) = 0;
     47    virtual void SetTimecode(int64_t timecode) = 0;
    4748    virtual bool IsPaused(void) const = 0;
    4849    virtual void Pause(bool paused) = 0;
    4950    virtual void PauseUntilBuffered(void) = 0;
    class MPUBLIC AudioOutput : public VolumeBase, public OutputListeners 
    5152    // Wait for all data to finish playing
    5253    virtual void Drain(void) = 0;
    5354
    54     virtual int GetAudiotime(void) = 0;
     55    virtual int64_t GetAudiotime(void) = 0;
    5556
    5657    /// report amount of audio buffered in milliseconds.
    57     virtual int GetAudioBufferedTime(void) { return 0; }
     58    virtual int64_t GetAudioBufferedTime(void) { return 0; }
    5859
    5960    virtual void SetSourceBitrate(int ) { }
    6061
  • mythtv/libs/libmyth/audiooutputbase.cpp

    diff --git a/mythtv/libs/libmyth/audiooutputbase.cpp b/mythtv/libs/libmyth/audiooutputbase.cpp
    index 9213adf..ec9dca1 100644
    a b AudioOutputBase::AudioOutputBase(const AudioSettings &settings) : 
    5656    passthru(false),            enc(false),
    5757    reenc(false),
    5858    stretchfactor(1.0f),
     59    eff_stretchfactor(100000),
    5960
    6061    source(settings.source),    killaudio(false),
    6162
    void AudioOutputBase::SetStretchFactorLocked(float lstretchfactor) 
    179180        return;
    180181
    181182    stretchfactor = lstretchfactor;
     183    eff_stretchfactor = (int)(100000.0f * lstretchfactor + 0.5);
    182184    if (pSoundStretch)
    183185    {
    184186        VBGENERAL(QString("Changing time stretch to %1").arg(stretchfactor));
    void AudioOutputBase::SetStretchFactorLocked(float lstretchfactor) 
    202204            bytes_per_frame = source_channels *
    203205                              AudioOutputSettings::SampleSize(FORMAT_FLT);
    204206            waud = raud = 0;
     207            reset_active.Ref();
    205208        }
    206209    }
    207210}
    bool AudioOutputBase::ToggleUpmix(void) 
    236239    audio_buflock.lock();
    237240    avsync_lock.lock();
    238241    waud = raud = 0;
     242    reset_active.Ref();
    239243
    240244    configured_channels =
    241245        configured_channels == max_channels ? 2 : max_channels;
    void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings) 
    311315    QMutexLocker lockav(&avsync_lock);
    312316
    313317    waud = raud = 0;
     318    reset_active.Clear();
    314319    actually_paused = processing = false;
    315320
    316321    channels               = settings.channels;
    void AudioOutputBase::Reset() 
    582587    QMutexLocker lock(&audio_buflock);
    583588    QMutexLocker lockav(&avsync_lock);
    584589
    585     raud = waud = audbuf_timecode = audiotime = frames_buffered = 0;
     590    audbuf_timecode = audiotime = frames_buffered = 0;
     591    waud = raud;    // empty ring buffer
     592    reset_active.Ref();
    586593    current_seconds = -1;
    587594    was_paused = !pauseaudio;
    588595
    void AudioOutputBase::Reset() 
    596603 * Used by mythmusic for seeking since it doesn't provide timecodes to
    597604 * AddSamples()
    598605 */
    599 void AudioOutputBase::SetTimecode(long long timecode)
     606void AudioOutputBase::SetTimecode(int64_t timecode)
    600607{
    601608    audbuf_timecode = audiotime = timecode;
    602     frames_buffered = (long long)((timecode * source_samplerate) / 1000);
     609    frames_buffered = (int64_t)((timecode * source_samplerate) / 1000);
    603610}
    604611
    605612/**
    int AudioOutputBase::audioready() 
    654661/**
    655662 * Calculate the timecode of the samples that are about to become audible
    656663 */
    657 int AudioOutputBase::GetAudiotime(void)
     664int64_t AudioOutputBase::GetAudiotime(void)
    658665{
    659666    if (audbuf_timecode == 0)
    660667        return 0;
    661668
    662     int soundcard_buffer = 0;
    663669    int obpf = output_bytes_per_frame;
    664     int totalbuffer;
    665     long long oldaudiotime;
     670    int64_t oldaudiotime;
    666671
    667672    /* We want to calculate 'audiotime', which is the timestamp of the audio
    668        which is leaving the sound card at this instant.
     673       Which is leaving the sound card at this instant.
    669674
    670675       We use these variables:
    671676
    int AudioOutputBase::GetAudiotime(void) 
    677682       'totalbuffer' is the total # of bytes in our audio buffer, and the
    678683       sound card's buffer. */
    679684
    680     soundcard_buffer = GetBufferedOnSoundcard(); // bytes
    681685
    682686    QMutexLocker lockav(&avsync_lock);
    683687
     688    int64_t soundcard_buffer = GetBufferedOnSoundcard(); // bytes
     689    int64_t main_buffer = audioready();
     690
    684691    /* audioready tells us how many bytes are in audiobuffer
    685692       scaled appropriately if output format != internal format */
    686     totalbuffer = audioready() + soundcard_buffer;
    687 
    688     if (needs_upmix && upmixer)
    689         totalbuffer += upmixer->frameLatency() * obpf;
    690 
    691     if (pSoundStretch)
    692     {
    693         totalbuffer += pSoundStretch->numUnprocessedSamples() * obpf /
    694                        stretchfactor;
    695         totalbuffer += pSoundStretch->numSamples() * obpf;
    696     }
    697 
    698     if (encoder)
    699         totalbuffer += encoder->Buffered();
    700693
    701694    oldaudiotime = audiotime;
    702695
    703     audiotime = audbuf_timecode - (long long)(totalbuffer) * 100000 *
    704                                         stretchfactor / (obpf * effdsp);
     696    // timecode is the stretch adjusted version
     697    // of major post-stretched buffer contents
     698    // processing latencies are catered for in AddSamples/SetAudiotime to eliminate
     699    // race
     700    audiotime = audbuf_timecode - (( (main_buffer + soundcard_buffer) * eff_stretchfactor ) / (effdsp * obpf));
    705701
    706702    /* audiotime should never go backwards, but we might get a negative
    707703       value if GetBufferedOnSoundcard() isn't updated by the driver very
    int AudioOutputBase::GetAudiotime(void) 
    709705    if (audiotime < oldaudiotime)
    710706        audiotime = oldaudiotime;
    711707
    712     VBAUDIOTS(QString("GetAudiotime audt=%3 atc=%4 tb=%5 sb=%6 "
    713                       "sr=%7 obpf=%8 sf=%9")
     708    VBAUDIOTS(QString("GetAudiotime audt=%1 atc=%2 mb=%3 sb=%4 tb=%5 "
     709                      "sr=%6 obpf=%7 bpf=%8 sf=%9 %10 %11")
    714710              .arg(audiotime).arg(audbuf_timecode)
    715               .arg(totalbuffer).arg(soundcard_buffer)
    716               .arg(samplerate).arg(obpf).arg(stretchfactor));
     711              .arg(main_buffer)
     712              .arg(soundcard_buffer)
     713              .arg(main_buffer+soundcard_buffer)
     714              .arg(samplerate).arg(obpf).arg(bytes_per_frame).arg(stretchfactor)
     715              .arg((main_buffer + soundcard_buffer) * eff_stretchfactor)
     716              .arg(( (main_buffer + soundcard_buffer) * eff_stretchfactor ) / (effdsp * obpf))
     717              );
     718
     719    return audiotime;
     720}
     721
     722/**
     723 * Set the timecode of the top of the ringbuffer
     724 * Exclude all other processing elements as they dont vary
     725 * between AddSamples calls
     726 */
     727void AudioOutputBase::SetAudiotime(int frames, int64_t timecode)
     728{
     729    int64_t processframes_stretched = 0;
     730    int64_t processframes_unstretched = 0;
     731
     732    if (needs_upmix && upmixer)
     733        processframes_unstretched -= upmixer->frameLatency();
    717734
    718     return (int)audiotime;
     735    if (pSoundStretch)
     736    {
     737        processframes_unstretched -= pSoundStretch->numUnprocessedSamples();
     738        processframes_stretched -= pSoundStretch->numSamples();
     739    }
     740
     741    if (encoder)
     742        // the input buffered data is still in audio_bytes_per_sample format
     743        processframes_stretched -= encoder->Buffered() / output_bytes_per_frame;
     744
     745    int64_t old_audbuf_timecode = audbuf_timecode;
     746
     747    audbuf_timecode = timecode +
     748                (((frames + processframes_unstretched) * 100000) +
     749                  (processframes_stretched * eff_stretchfactor )) / effdsp;
     750
     751    // check for timecode wrap and reset audiotime if detected
     752    // timecode will always be monotonic asc if not seeked and reset
     753    // happens if seek or pause happens
     754    if (audbuf_timecode < old_audbuf_timecode)
     755        audiotime = 0;
     756
     757    VBAUDIOTS(QString("SetAudiotime atc=%1 tc=%2 f=%3 pfu=%4 pfs=%5")
     758              .arg(audbuf_timecode)
     759              .arg(timecode)
     760              .arg(frames)
     761              .arg(processframes_unstretched)
     762              .arg(processframes_stretched));
     763#ifdef AUDIOTSTESTING
     764    GetAudiotime();
     765#endif
    719766}
    720767
    721768/**
    int AudioOutputBase::GetAudiotime(void) 
    723770 * audible and the samples most recently added to the audiobuffer, i.e. the
    724771 * time in ms representing the sum total of buffered samples
    725772 */
    726 int AudioOutputBase::GetAudioBufferedTime(void)
     773int64_t AudioOutputBase::GetAudioBufferedTime(void)
    727774{
    728775    int ret = audbuf_timecode - GetAudiotime();
    729776    // Pulse can give us values that make this -ve
    int AudioOutputBase::CopyWithUpmix(char *buffer, int frames, int &org_waud) 
    869916 *
    870917 * Returns false if there's not enough space right now
    871918 */
    872 bool AudioOutputBase::AddSamples(void *buffer, int frames, long long timecode)
     919bool AudioOutputBase::AddSamples(void *buffer, int in_frames, int64_t timecode)
    873920{
    874921    int org_waud = waud,               afree = audiofree();
    875     int bpf      = bytes_per_frame,    len   = frames * source_bytes_per_frame;
     922    int frames = in_frames;
     923    int bpf      = bytes_per_frame,    len   = in_frames * source_bytes_per_frame;
    876924    int used     = kAudioRingBufferSize - afree;
    877925    bool music   = false;
     926    int bdiff;
    878927
    879928    VBAUDIOTS(QString("AddSamples frames=%1, bytes=%2, used=%3, free=%4, "
    880929                      "timecode=%5 needsupmix=%6")
    bool AudioOutputBase::AddSamples(void *buffer, int frames, long long timecode) 
    896945    if (timecode < 0)
    897946    {
    898947        // Send original samples to mythmusic visualisation
    899         timecode = (long long)(frames_buffered) * 1000 / source_samplerate;
     948        timecode = (int64_t)(frames_buffered) * 1000 / source_samplerate;
    900949        frames_buffered += frames;
    901950        dispatchVisual((uchar *)buffer, len, timecode, source_channels,
    902951                       output_settings->FormatToBits(format));
    bool AudioOutputBase::AddSamples(void *buffer, int frames, long long timecode) 
    949998                    .arg(src_strerror(error)));
    950999
    9511000        buffer = src_out;
    952         frames = src_data.output_frames_gen;
     1001        in_frames = frames = src_data.output_frames_gen;
    9531002    }
    9541003    else if (processing)
    9551004        buffer = src_in;
    bool AudioOutputBase::AddSamples(void *buffer, int frames, long long timecode) 
    9571006    /* we want the timecode of the last sample added but we are given the
    9581007       timecode of the first - add the time in ms that the frames added
    9591008       represent */
    960     audbuf_timecode = timecode + ((long long)(frames) * 100000 / effdsp);
    9611009
    9621010    // Copy samples into audiobuffer, with upmix if necessary
    9631011    if ((len = CopyWithUpmix((char *)buffer, frames, org_waud)) <= 0)
    964         return true;
     1012    {
     1013        //return true;
     1014        goto done;
     1015    }
    9651016
    9661017    frames = len / bpf;
    9671018
    968     int bdiff = kAudioRingBufferSize - waud;
     1019    bdiff = kAudioRingBufferSize - waud;
    9691020
    9701021    if (pSoundStretch)
    9711022    {
    bool AudioOutputBase::AddSamples(void *buffer, int frames, long long timecode) 
    10431094
    10441095    waud = org_waud;
    10451096
     1097done:
     1098    SetAudiotime(in_frames, timecode);
     1099
    10461100    return true;
    10471101}
    10481102
    void AudioOutputBase::OutputAudioLoop(void) 
    10901144    uchar *fragment_buf = new uchar[fragment_size + 16];
    10911145    uchar *fragment     = (uchar *)AOALIGN(fragment_buf[0]);
    10921146
     1147    // to reduce startup latency, write silence in 8ms chunks
     1148    int zero_fragment_size = (int)(0.008*samplerate/channels);
     1149    zero_fragment_size *= bytes_per_frame;   // make sure its a multiple of bytes_per_frame
     1150    if (zero_fragment_size > fragment_size)
     1151        zero_fragment_size = fragment_size;
     1152
    10931153    bzero(zeros, fragment_size);
    10941154
    10951155    while (!killaudio)
    void AudioOutputBase::OutputAudioLoop(void) 
    11381198            continue;
    11391199        }
    11401200
     1201#ifdef AUDIOTSTESTING
     1202        VBAUDIOTS("WriteAudio Start");
     1203#endif
    11411204        Status();
    11421205
    1143         if (GetAudioData(fragment, fragment_size, true))
    1144             WriteAudio(fragment, fragment_size);
     1206        // delay setting raud until after phys buffer is filled
     1207        // so GetAudiotime will be accurate without locking
     1208        reset_active.TestAndDeref();
     1209        int next_raud = raud;
     1210        if (GetAudioData(fragment, fragment_size, true, &next_raud))
     1211        {
     1212            if (!reset_active.TestAndDeref())
     1213            {
     1214                WriteAudio(fragment, fragment_size);
     1215                if (!reset_active.TestAndDeref())
     1216                    raud = next_raud;
     1217            }
     1218        }
     1219#ifdef AUDIOTSTESTING
     1220        GetAudiotime();
     1221        VBAUDIOTS("WriteAudio Done");
     1222#endif
     1223
    11451224    }
    11461225
    11471226    delete[] zeros;
    void AudioOutputBase::OutputAudioLoop(void) 
    11581237 * nothing. Otherwise, we'll copy less than 'size' bytes if that's all that's
    11591238 * available. Returns the number of bytes copied.
    11601239 */
    1161 int AudioOutputBase::GetAudioData(uchar *buffer, int size, bool full_buffer)
     1240int AudioOutputBase::GetAudioData(uchar *buffer, int size, bool full_buffer, int *local_raud)
    11621241{
    11631242
     1243#define LRPOS audiobuffer + *local_raud
    11641244    // re-check audioready() in case things changed.
    11651245    // for example, ClearAfterSeek() might have run
    11661246    int avail_size   = audioready();
    11671247    int frag_size    = size;
    11681248    int written_size = size;
    11691249
     1250    if (local_raud == NULL)
     1251        local_raud = &raud;
     1252
    11701253    if (!full_buffer && (size > avail_size))
    11711254    {
    11721255        // when full_buffer is false, return any available data
    int AudioOutputBase::GetAudioData(uchar *buffer, int size, bool full_buffer) 
    11921275    {
    11931276        if (fromFloats)
    11941277            off = AudioOutputUtil::fromFloat(output_format, buffer,
    1195                                              RPOS, bdiff);
     1278                                             LRPOS, bdiff);
    11961279        else
    11971280        {
    1198             memcpy(buffer, RPOS, bdiff);
     1281            memcpy(buffer, LRPOS, bdiff);
    11991282            off = bdiff;
    12001283        }
    12011284
    12021285        frag_size -= bdiff;
    1203         raud = 0;
     1286        *local_raud = 0;
    12041287    }
    12051288    if (frag_size > 0)
    12061289    {
    12071290        if (fromFloats)
    12081291            AudioOutputUtil::fromFloat(output_format, buffer + off,
    1209                                        RPOS, frag_size);
     1292                                       LRPOS, frag_size);
    12101293        else
    1211             memcpy(buffer + off, RPOS, frag_size);
     1294            memcpy(buffer + off, LRPOS, frag_size);
    12121295    }
    12131296
    1214     raud += frag_size;
     1297    *local_raud += frag_size;
    12151298
    12161299    // Mute individual channels through mono->stereo duplication
    12171300    MuteState mute_state = GetMuteState();
  • mythtv/libs/libmyth/audiooutputbase.h

    diff --git a/mythtv/libs/libmyth/audiooutputbase.h b/mythtv/libs/libmyth/audiooutputbase.h
    index 51e9be6..84e709d 100644
    a b class FreeSurround; 
    3232class AudioOutputDigitalEncoder;
    3333struct AVCodecContext;
    3434
     35class AsyncLooseLock
     36{
     37public:
     38    AsyncLooseLock() { head = tail = 0; }
     39    void Clear() { head = tail = 0; }
     40    void Ref() { head++; }
     41    bool TestAndDeref() { bool r; if ((r=(head != tail))) tail++; return r; }
     42private:
     43    int head;
     44    int tail;
     45};
     46
    3547class AudioOutputBase : public AudioOutput, public QThread
    3648{
    3749 public:
    class AudioOutputBase : public AudioOutput, public QThread 
    5769    int GetSWVolume(void);
    5870
    5971    // timecode is in milliseconds.
    60     virtual bool AddSamples(void *buffer, int frames, long long timecode);
     72    virtual bool AddSamples(void *buffer, int frames, int64_t timecode);
    6173
    62     virtual void SetTimecode(long long timecode);
     74    virtual void SetTimecode(int64_t timecode);
    6375    virtual bool IsPaused(void) const { return actually_paused; }
    6476    virtual void Pause(bool paused);
    6577    void PauseUntilBuffered(void);
    class AudioOutputBase : public AudioOutput, public QThread 
    6779    // Wait for all data to finish playing
    6880    virtual void Drain(void);
    6981
    70     virtual int GetAudiotime(void);
    71     virtual int GetAudioBufferedTime(void);
     82    virtual int64_t GetAudiotime(void);
     83    virtual int64_t GetAudioBufferedTime(void);
    7284
    7385    // Send output events showing current progress
    7486    virtual void Status(void);
    class AudioOutputBase : public AudioOutput, public QThread 
    8395
    8496    static const uint kAudioSRCInputSize  = 16384<<1;
    8597    static const uint kAudioSRCOutputSize = 16384<<3;
    86     /// Audio Buffer Size -- should be divisible by 12,10,8,6,4,2..
    87     static const uint kAudioRingBufferSize   = 1536000;
     98    /// Audio Buffer Size -- should be divisible by 32,24,16,12,10,8,6,4,2..
     99    static const uint kAudioRingBufferSize   = 3072000;
    88100
    89101 protected:
    90102    // You need to implement the following functions
    class AudioOutputBase : public AudioOutput, public QThread 
    102114    virtual bool StartOutputThread(void);
    103115    virtual void StopOutputThread(void);
    104116
    105     int GetAudioData(uchar *buffer, int buf_size, bool fill_buffer);
     117    int GetAudioData(uchar *buffer, int buf_size, bool fill_buffer, int *local_raud = NULL);
    106118
    107119    void OutputAudioLoop(void);
    108120
    class AudioOutputBase : public AudioOutput, public QThread 
    138150    bool passthru, enc, reenc;
    139151
    140152    float stretchfactor;
     153    int  eff_stretchfactor;     // scaled to 100000 as effdsp is
    141154    AudioOutputSource source;
    142155
    143156    bool killaudio;
    class AudioOutputBase : public AudioOutput, public QThread 
    153166
    154167 private:
    155168    int CopyWithUpmix(char *buffer, int frames, int &org_waud);
     169    void SetAudiotime(int frames, int64_t timecode);
    156170    AudioOutputSettings *output_settings;
    157171    bool need_resampler;
    158172    SRC_STATE *src_ctx;
    class AudioOutputBase : public AudioOutput, public QThread 
    173187
    174188    bool processing;
    175189
    176     long long frames_buffered;
     190    int64_t frames_buffered;
    177191
    178192    bool audio_thread_exists;
    179193
    class AudioOutputBase : public AudioOutput, public QThread 
    186200    QMutex avsync_lock;
    187201
    188202    // timecode of audio leaving the soundcard (same units as timecodes)
    189     long long audiotime;
     203    int64_t audiotime;
    190204
    191205    /* Audio circular buffer */
    192206    int raud, waud;     /* read and write positions */
    193207    // timecode of audio most recently placed into buffer
    194     long long audbuf_timecode;
     208    int64_t audbuf_timecode;
     209    AsyncLooseLock reset_active;
    195210
    196211    QMutex killAudioLock;
    197212
  • mythtv/libs/libmythfreesurround/freesurround.cpp

    diff --git a/mythtv/libs/libmythfreesurround/freesurround.cpp b/mythtv/libs/libmythfreesurround/freesurround.cpp
    index 5e8b1f5..aef65a3 100644
    a b Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 
    2929using namespace std;
    3030
    3131#include "compat.h"
     32#include "mythverbose.h"
    3233#include "freesurround.h"
    3334#include "el_processor.h"
    3435
    3536#include <QString>
    3637#include <QDateTime>
    3738
    38 #if 0
    39 #define VERBOSE(args...) \
    40     do { \
    41         QDateTime dtmp = QDateTime::currentDateTime(); \
    42         QString dtime = dtmp.toString("yyyy-MM-dd hh:mm:ss.zzz"); \
    43         std::cout << dtime.toLocal8Bit().constData() << " " \
    44             << QString(args).toLocal8Bit().constData() << std::endl; \
    45     } while (0)
    46 #else
    47 #define VERBOSE(args...)
    48 #endif
    49 #if 0
    50 #define VERBOSE1(args...) \
    51     do { \
    52         QDateTime dtmp = QDateTime::currentDateTime(); \
    53         QString dtime = dtmp.toString("yyyy-MM-dd hh:mm:ss.zzz"); \
    54         std::cout << dtime.toLocal8Bit().constData() << " " \
    55             << QString(args).toLocal8Bit().constData() << std::endl; \
    56     } while (0)
    57 #else
    58 #define VERBOSE1(args...)
    59 #endif
    60 
    6139// our default internal block size, in floats
    6240static const unsigned default_block_size = 8192;
    6341// Gain of center and lfe channels in passive mode (sqrt 0.5)
    FreeSurround::FreeSurround(uint srate, bool moviemode, SurroundMode smode) : 
    161139    processed_size(0),
    162140    surround_mode(smode)
    163141{
    164     VERBOSE(QString("FreeSurround::FreeSurround rate %1 moviemode %2")
     142    VERBOSE(VB_AUDIO+VB_EXTRA, QString("FreeSurround::FreeSurround rate %1 moviemode %2")
    165143            .arg(srate).arg(moviemode));
    166144
    167145    if (moviemode)
    FreeSurround::FreeSurround(uint srate, bool moviemode, SurroundMode smode) : 
    193171    channel_select++;
    194172    if (channel_select>=6)
    195173        channel_select = 0;
    196     VERBOSE(QString("FreeSurround::FreeSurround channel_select %1")
     174    VERBOSE(VB_AUDIO+VB_EXTRA, QString("FreeSurround::FreeSurround channel_select %1")
    197175            .arg(channel_select));
    198176#endif
    199     VERBOSE(QString("FreeSurround::FreeSurround done"));
     177    VERBOSE(VB_AUDIO+VB_EXTRA, QString("FreeSurround::FreeSurround done"));
    200178}
    201179
    202180void FreeSurround::SetParams()
    FreeSurround::fsurround_params::fsurround_params(int32_t center_width, 
    224202
    225203FreeSurround::~FreeSurround()
    226204{
    227     VERBOSE(QString("FreeSurround::~FreeSurround"));
     205    VERBOSE(VB_AUDIO+VB_EXTRA, QString("FreeSurround::~FreeSurround"));
    228206    close();
    229207    if (bufs)
    230208    {
    231209        bp.release((void*)1);
    232210        bufs = NULL;
    233211    }
    234     VERBOSE(QString("FreeSurround::~FreeSurround done"));
     212    VERBOSE(VB_AUDIO+VB_EXTRA, QString("FreeSurround::~FreeSurround done"));
    235213}
    236214
    237215uint FreeSurround::putFrames(void* buffer, uint numFrames, uint numChannels)
    uint FreeSurround::putFrames(void* buffer, uint numFrames, uint numChannels) 
    289267                    break;
    290268            }
    291269            ic += numFrames;
    292             in_count = ic;
    293270            processed = process;
    294271            if (ic != bs)
     272            {
     273                // dont modify unless no processing is to be done
     274                // for audiotime consistency
     275                in_count = ic;
    295276                break;
    296             in_count = 0;
     277            }
     278            // process_block takes some time so dont update in and out count
     279            // before its finished so that Audiotime is correctly calculated
    297280            if (process)
    298281                process_block();
     282            in_count = 0;
    299283            out_count = bs;
    300284            processed_size = bs;
    301285            break;
    302286    }
    303287
    304     VERBOSE1(QString("FreeSurround::putFrames %1 %2 used %4 generated %5")
     288    VERBOSE(VB_AUDIO+VB_TIMESTAMP+VB_EXTRA, QString("FreeSurround::putFrames %1 #ch %2 used %4 generated %5")
    305289            .arg(numFrames).arg(numChannels).arg(i).arg(out_count));
    306290
    307291    return i;
    uint FreeSurround::receiveFrames(void *buffer, uint maxFrames) 
    318302    switch (surround_mode)
    319303    {
    320304        case SurroundModePassive:
    321             for (uint i = 0; i < maxFrames; i++)
     305            for (i = 0; i < maxFrames; i++)
    322306            {
    323307                *output++ = bufs->l[outindex];
    324308                *output++ = bufs->r[outindex];
    uint FreeSurround::receiveFrames(void *buffer, uint maxFrames) 
    341325                float *ls  = &outputs[3][outindex];
    342326                float *rs  = &outputs[4][outindex];
    343327                float *lfe = &outputs[5][outindex];
    344                 for (uint i = 0; i < maxFrames; i++)
     328                for (i = 0; i < maxFrames; i++)
    345329                {
    346330                    *output++ = *l++;
    347331                    *output++ = *r++;
    uint FreeSurround::receiveFrames(void *buffer, uint maxFrames) 
    361345                float *ls  = &bufs->ls[outindex];
    362346                float *rs  = &bufs->rs[outindex];
    363347                float *lfe = &bufs->lfe[outindex];
    364                 for (uint i = 0; i < maxFrames; i++)
     348                for (i = 0; i < maxFrames; i++)
    365349                {
    366350                    *output++ = *l++;
    367351                    *output++ = *r++;
    uint FreeSurround::receiveFrames(void *buffer, uint maxFrames) 
    376360            break;
    377361    }
    378362    out_count = oc;
    379     VERBOSE1(QString("FreeSurround::receiveFrames %1").arg(maxFrames));
     363    VERBOSE(VB_AUDIO+VB_TIMESTAMP+VB_EXTRA, QString("FreeSurround::receiveFrames %1").arg(maxFrames));
    380364    return maxFrames;
    381365}
    382366