Skip to content
This repository
Browse code

Merge pull request #3259 from FernetMenta/aefixes

Audio fixes
  • Loading branch information...
commit 555354d4a64d8de5b6e03023b011782d2c558304 2 parents 25bf01a + 2c88347
Peter Frühberger authored September 13, 2013
3  xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp
@@ -93,8 +93,10 @@ bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst
93 93
     // remapLayout is the layout of the sink, if the channel is in our src layout
94 94
     // the channel is mapped by setting coef 1.0
95 95
     memset(m_rematrix, 0, sizeof(m_rematrix));
  96
+    m_dst_chan_layout = 0;
96 97
     for (unsigned int out=0; out<remapLayout->Count(); out++)
97 98
     {
  99
+      m_dst_chan_layout += (1 << out);
98 100
       int idx = GetAVChannelIndex((*remapLayout)[out], m_src_chan_layout);
99 101
       if (idx >= 0)
100 102
       {
@@ -102,7 +104,6 @@ bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst
102 104
       }
103 105
     }
104 106
 
105  
-    m_dst_chan_layout = m_dllAvUtil.av_get_default_channel_layout(m_dst_channels);
106 107
     m_dllAvUtil.av_opt_set_int(m_pContext, "out_channel_count", m_dst_channels, 0);
107 108
     m_dllAvUtil.av_opt_set_int(m_pContext, "out_channel_layout", m_dst_chan_layout, 0);
108 109
 
37  xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp
@@ -53,10 +53,13 @@ CActiveAEStream::CActiveAEStream(AEAudioFormat *format)
53 53
   m_streamIsBuffering = true;
54 54
   m_streamSlave = NULL;
55 55
   m_convertFn = NULL;
  56
+  m_leftoverBuffer = new uint8_t[m_format.m_frameSize];
  57
+  m_leftoverBytes = 0;
56 58
 }
57 59
 
58 60
 CActiveAEStream::~CActiveAEStream()
59 61
 {
  62
+  delete [] m_leftoverBuffer;
60 63
 }
61 64
 
62 65
 void CActiveAEStream::IncFreeBuffers()
@@ -88,10 +91,28 @@ unsigned int CActiveAEStream::AddData(void *data, unsigned int size)
88 91
   Message *msg;
89 92
   unsigned int copied = 0;
90 93
   int bytesToCopy = size;
  94
+  uint8_t *buf = (uint8_t*)data;
  95
+
91 96
   while(copied < size)
92 97
   {
  98
+    buf = (uint8_t*)data;
  99
+    bytesToCopy = size - copied;
  100
+
93 101
     if (m_currentBuffer)
94 102
     {
  103
+      // fill leftover buffer and copy it first
  104
+      if (m_leftoverBytes && bytesToCopy >= (m_format.m_frameSize - m_leftoverBytes))
  105
+      {
  106
+        int fillbytes = m_format.m_frameSize - m_leftoverBytes;
  107
+        memcpy(m_leftoverBuffer+m_leftoverBytes, (uint8_t*)data, fillbytes);
  108
+        data = (uint8_t*)data + fillbytes;
  109
+        size -= fillbytes;
  110
+        // leftover buffer will be copied on next cycle
  111
+        buf = m_leftoverBuffer;
  112
+        bytesToCopy = m_format.m_frameSize;
  113
+        m_leftoverBytes = 0;
  114
+      }
  115
+
95 116
       int start = m_currentBuffer->pkt->nb_samples *
96 117
                   m_currentBuffer->pkt->bytes_per_sample *
97 118
                   m_currentBuffer->pkt->config.channels /
@@ -99,20 +120,29 @@ unsigned int CActiveAEStream::AddData(void *data, unsigned int size)
99 120
 
100 121
       int freeSamples = m_currentBuffer->pkt->max_nb_samples - m_currentBuffer->pkt->nb_samples;
101 122
       int availableSamples = bytesToCopy / m_format.m_frameSize;
  123
+
  124
+      // if we don't have a full frame, copy to leftover buffer
  125
+      if (!availableSamples && bytesToCopy)
  126
+      {
  127
+        memcpy(m_leftoverBuffer+m_leftoverBytes, buf+copied, bytesToCopy);
  128
+        m_leftoverBytes = bytesToCopy;
  129
+        copied += bytesToCopy;
  130
+      }
  131
+
102 132
       int samples = std::min(freeSamples, availableSamples);
103 133
       int bytes = samples * m_format.m_frameSize;
  134
+
104 135
       //TODO: handle planar formats
105 136
       if (m_convertFn)
106  
-        m_convertFn((uint8_t*)data+copied, samples*m_currentBuffer->pkt->config.channels, (float*)(m_currentBuffer->pkt->data[0] + start));
  137
+        m_convertFn(buf+copied, samples*m_currentBuffer->pkt->config.channels, (float*)(m_currentBuffer->pkt->data[0] + start));
107 138
       else
108  
-        memcpy(m_currentBuffer->pkt->data[0] + start, (uint8_t*)data+copied, bytes);
  139
+        memcpy(m_currentBuffer->pkt->data[0] + start, buf+copied, bytes);
109 140
       {
110 141
         CSingleLock lock(*m_statsLock);
111 142
         m_currentBuffer->pkt->nb_samples += samples;
112 143
         m_bufferedTime += (double)samples / m_currentBuffer->pkt->config.sample_rate;
113 144
       }
114 145
       copied += bytes;
115  
-      bytesToCopy -= bytes;
116 146
       if (m_currentBuffer->pkt->nb_samples == m_currentBuffer->pkt->max_nb_samples)
117 147
       {
118 148
         MsgStreamSample msgData;
@@ -249,6 +279,7 @@ bool CActiveAEStream::IsDrained()
249 279
 void CActiveAEStream::Flush()
250 280
 {
251 281
   m_currentBuffer = NULL;
  282
+  m_leftoverBytes = 0;
252 283
   AE.FlushStream(this);
253 284
   ResetFreeBuffers();
254 285
 }
2  xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.h
@@ -92,6 +92,8 @@ class CActiveAEStream : public IAEStream
92 92
   IAEStream *m_streamSlave;
93 93
   CAEConvert::AEConvertToFn m_convertFn;
94 94
   CCriticalSection m_streamLock;
  95
+  uint8_t *m_leftoverBuffer;
  96
+  int m_leftoverBytes;
95 97
 
96 98
   // only accessed by engine
97 99
   CActiveAEBufferPool *m_inputBuffers;
8  xbmc/cores/paplayer/FLACcodec.cpp
@@ -311,17 +311,19 @@ void FLACCodec::DecoderMetadataCallback(const FLAC__StreamDecoder *decoder, cons
311 311
 
312 312
   if (metadata->type==FLAC__METADATA_TYPE_STREAMINFO)
313 313
   {
314  
-    static enum AEChannel map[6][7] = {
  314
+    static enum AEChannel map[8][9] = {
315 315
       {AE_CH_FC, AE_CH_NULL},
316 316
       {AE_CH_FL, AE_CH_FR, AE_CH_NULL},
317 317
       {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_NULL},
318 318
       {AE_CH_FL, AE_CH_FR, AE_CH_BL, AE_CH_BR, AE_CH_NULL},
319 319
       {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_BL, AE_CH_BR, AE_CH_NULL},
320  
-      {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_LFE, AE_CH_BL, AE_CH_BR, AE_CH_NULL}
  320
+      {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_LFE, AE_CH_BL, AE_CH_BR, AE_CH_NULL}, // 6 channels
  321
+      {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_LFE, AE_CH_BC, AE_CH_BL, AE_CH_BR, AE_CH_NULL}, // 7 channels
  322
+      {AE_CH_FL, AE_CH_FR, AE_CH_FC, AE_CH_LFE, AE_CH_BL, AE_CH_BR, AE_CH_SL, AE_CH_SR, AE_CH_NULL} // 8 channels
321 323
     };
322 324
 
323 325
     /* channel counts greater then 6 are undefined */
324  
-    if (metadata->data.stream_info.channels > 6)
  326
+    if (metadata->data.stream_info.channels > 8)
325 327
       pThis->m_ChannelInfo = CAEUtil::GuessChLayout(metadata->data.stream_info.channels);
326 328
     else
327 329
       pThis->m_ChannelInfo = CAEChannelInfo(map[metadata->data.stream_info.channels - 1]);

0 notes on commit 555354d

Please sign in to comment.
Something went wrong with that request. Please try again.