Ticket #8500: accurate_audiots.2.patch

File accurate_audiots.2.patch, 23.8 KB (added by Mark Spieth, 9 years ago)

with reset race fix

  • mythtv/libs/libmyth/audiooutput.h

    commit 8ef87b6b0534a2656ec4307819e0749f6c49d4e5
    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..dbb3815 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    audbuf_timecode = timecode +
     746                (((frames + processframes_unstretched) * 100000) +
     747                  (processframes_stretched * eff_stretchfactor )) / effdsp;
     748
     749    VBAUDIOTS(QString("SetAudiotime atc=%1 tc=%2 f=%3 pfu=%4 pfs=%5")
     750              .arg(audbuf_timecode)
     751              .arg(timecode)
     752              .arg(frames)
     753              .arg(processframes_unstretched)
     754              .arg(processframes_stretched));
     755#ifdef AUDIOTSTESTING
     756    GetAudiotime();
     757#endif
    719758}
    720759
    721760/**
    int AudioOutputBase::GetAudiotime(void) 
    723762 * audible and the samples most recently added to the audiobuffer, i.e. the
    724763 * time in ms representing the sum total of buffered samples
    725764 */
    726 int AudioOutputBase::GetAudioBufferedTime(void)
     765int64_t AudioOutputBase::GetAudioBufferedTime(void)
    727766{
    728767    int ret = audbuf_timecode - GetAudiotime();
    729768    // Pulse can give us values that make this -ve
    int AudioOutputBase::CopyWithUpmix(char *buffer, int frames, int &org_waud) 
    869908 *
    870909 * Returns false if there's not enough space right now
    871910 */
    872 bool AudioOutputBase::AddSamples(void *buffer, int frames, long long timecode)
     911bool AudioOutputBase::AddSamples(void *buffer, int in_frames, int64_t timecode)
    873912{
    874913    int org_waud = waud,               afree = audiofree();
    875     int bpf      = bytes_per_frame,    len   = frames * source_bytes_per_frame;
     914    int frames = in_frames;
     915    int bpf      = bytes_per_frame,    len   = in_frames * source_bytes_per_frame;
    876916    int used     = kAudioRingBufferSize - afree;
    877917    bool music   = false;
     918    int bdiff;
    878919
    879920    VBAUDIOTS(QString("AddSamples frames=%1, bytes=%2, used=%3, free=%4, "
    880921                      "timecode=%5 needsupmix=%6")
    bool AudioOutputBase::AddSamples(void *buffer, int frames, long long timecode) 
    896937    if (timecode < 0)
    897938    {
    898939        // Send original samples to mythmusic visualisation
    899         timecode = (long long)(frames_buffered) * 1000 / source_samplerate;
     940        timecode = (int64_t)(frames_buffered) * 1000 / source_samplerate;
    900941        frames_buffered += frames;
    901942        dispatchVisual((uchar *)buffer, len, timecode, source_channels,
    902943                       output_settings->FormatToBits(format));
    bool AudioOutputBase::AddSamples(void *buffer, int frames, long long timecode) 
    949990                    .arg(src_strerror(error)));
    950991
    951992        buffer = src_out;
    952         frames = src_data.output_frames_gen;
     993        in_frames = frames = src_data.output_frames_gen;
    953994    }
    954995    else if (processing)
    955996        buffer = src_in;
    bool AudioOutputBase::AddSamples(void *buffer, int frames, long long timecode) 
    957998    /* we want the timecode of the last sample added but we are given the
    958999       timecode of the first - add the time in ms that the frames added
    9591000       represent */
    960     audbuf_timecode = timecode + ((long long)(frames) * 100000 / effdsp);
     1001    //audbuf_timecode = timecode + ((int64_t)((frames) * 100000) / effdsp);
    9611002
    9621003    // Copy samples into audiobuffer, with upmix if necessary
    9631004    if ((len = CopyWithUpmix((char *)buffer, frames, org_waud)) <= 0)
    964         return true;
     1005    {
     1006        //return true;
     1007        goto done;
     1008    }
    9651009
    9661010    frames = len / bpf;
    9671011
    968     int bdiff = kAudioRingBufferSize - waud;
     1012    bdiff = kAudioRingBufferSize - waud;
    9691013
    9701014    if (pSoundStretch)
    9711015    {
    bool AudioOutputBase::AddSamples(void *buffer, int frames, long long timecode) 
    10431087
    10441088    waud = org_waud;
    10451089
     1090done:
     1091    SetAudiotime(in_frames, timecode);
     1092
    10461093    return true;
    10471094}
    10481095
    void AudioOutputBase::OutputAudioLoop(void) 
    10901137    uchar *fragment_buf = new uchar[fragment_size + 16];
    10911138    uchar *fragment     = (uchar *)AOALIGN(fragment_buf[0]);
    10921139
     1140    // to reduce startup latency, write silence in 8ms chunks
     1141    int zero_fragment_size = (int)(0.008*samplerate/channels);
     1142    zero_fragment_size *= bytes_per_frame;   // make sure its a multiple of bytes_per_frame
     1143    if (zero_fragment_size > fragment_size)
     1144        zero_fragment_size = fragment_size;
     1145
    10931146    bzero(zeros, fragment_size);
    10941147
    10951148    while (!killaudio)
    void AudioOutputBase::OutputAudioLoop(void) 
    11381191            continue;
    11391192        }
    11401193
     1194#ifdef AUDIOTSTESTING
     1195        VBAUDIOTS("WriteAudio Start");
     1196#endif
    11411197        Status();
    11421198
    1143         if (GetAudioData(fragment, fragment_size, true))
    1144             WriteAudio(fragment, fragment_size);
     1199        // delay setting raud until after phys buffer is filled
     1200        // so GetAudiotime will be accurate without locking
     1201        reset_active.TestAndDeref();
     1202        int next_raud = raud;
     1203        if (GetAudioData(fragment, fragment_size, true, &next_raud))
     1204        {
     1205            if (!reset_active.TestAndDeref())
     1206            {
     1207                WriteAudio(fragment, fragment_size);
     1208                if (!reset_active.TestAndDeref())
     1209                    raud = next_raud;
     1210            }
     1211        }
     1212#ifdef AUDIOTSTESTING
     1213        GetAudiotime();
     1214        VBAUDIOTS("WriteAudio Done");
     1215#endif
     1216
    11451217    }
    11461218
    11471219    delete[] zeros;
    void AudioOutputBase::OutputAudioLoop(void) 
    11581230 * nothing. Otherwise, we'll copy less than 'size' bytes if that's all that's
    11591231 * available. Returns the number of bytes copied.
    11601232 */
    1161 int AudioOutputBase::GetAudioData(uchar *buffer, int size, bool full_buffer)
     1233int AudioOutputBase::GetAudioData(uchar *buffer, int size, bool full_buffer, int *local_raud)
    11621234{
    11631235
     1236#define LRPOS audiobuffer + *local_raud
    11641237    // re-check audioready() in case things changed.
    11651238    // for example, ClearAfterSeek() might have run
    11661239    int avail_size   = audioready();
    11671240    int frag_size    = size;
    11681241    int written_size = size;
    11691242
     1243    if (local_raud == NULL)
     1244        local_raud = &raud;
     1245
    11701246    if (!full_buffer && (size > avail_size))
    11711247    {
    11721248        // when full_buffer is false, return any available data
    int AudioOutputBase::GetAudioData(uchar *buffer, int size, bool full_buffer) 
    11921268    {
    11931269        if (fromFloats)
    11941270            off = AudioOutputUtil::fromFloat(output_format, buffer,
    1195                                              RPOS, bdiff);
     1271                                             LRPOS, bdiff);
    11961272        else
    11971273        {
    1198             memcpy(buffer, RPOS, bdiff);
     1274            memcpy(buffer, LRPOS, bdiff);
    11991275            off = bdiff;
    12001276        }
    12011277
    12021278        frag_size -= bdiff;
    1203         raud = 0;
     1279        *local_raud = 0;
    12041280    }
    12051281    if (frag_size > 0)
    12061282    {
    12071283        if (fromFloats)
    12081284            AudioOutputUtil::fromFloat(output_format, buffer + off,
    1209                                        RPOS, frag_size);
     1285                                       LRPOS, frag_size);
    12101286        else
    1211             memcpy(buffer + off, RPOS, frag_size);
     1287            memcpy(buffer + off, LRPOS, frag_size);
    12121288    }
    12131289
    1214     raud += frag_size;
     1290    *local_raud += frag_size;
    12151291
    12161292    // Mute individual channels through mono->stereo duplication
    12171293    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