<div class="gmail_quote">On Wed, Jul 4, 2012 at 3:12 PM, Anton Khirnov <span dir="ltr"><<a href="mailto:anton@khirnov.net" target="_blank">anton@khirnov.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<br>
Hi,<br>
could you provide more complete code samples. Like what does your<br>
get_audio_frame() look like (did you do any modifications to it?) or how<br>
exactly are you calling it.<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Anton Khirnov<br>
</font></span></blockquote></div><br>Sure, no problem.<br><br clear="all">Full code download here: <br><b><a href="http://corp.productiveconcepts.com/qt-libav-recording-test-20120705.tar.gz">http://corp.productiveconcepts.com/qt-libav-recording-test-20120705.tar.gz</a></b><br>

<br><i>Untar, cd into qtmultimedia/audio_inp_test, qmake and make, then run ./recorder. (yes, you must have the Qt SDK installed (>= ver 4.6.2, not tested with >= 5.0), and you must use qmake to generate the Makefile.)<br>

</i><br>If you just want to look at the code in context, I've attached the *very very messy* code (recorder.cpp) to this email. It's basically a hacked-up version output-example2 - scroll down to line 151 where get_audio_frame() starts. <br>

<br>To answer your question, get_audio_frame() is called from write_audio_frame() (from the original output-example2 code) as "get_audio_frame(samples, audio_input_frame_size, c->channels);"<br><br>And, yes - I made *extensive* modifications to get_audio_frame() to try to get it tied together with Qt's audio code.<br>

<br>Since it's short, here's the get_audio_frame() code, below. <br><br><b>A quick walkthru:</b><br><br>* Basically, first it grabs a packet from the "buffer" (captured by Qt code in  Recorder::sampleIO()) and plays back that audio packet over the speakers - this way, I know the capture code is working and the audio data is valid.<br>

<br>* Then it pushes the audio data onto a "writeBuffer" (just a QByteArray) - since the frame_size*2 value is often smaller than amount of data in an AudioPacket, I must buffer the data for writing.<br><br>* Next, if the writeBuffer isn't empty, it copies frame_size*2 bytes from the writeBuffer into the int16_t* samples pointer given to get_audio_frame() and removes the same number of bytes from the head of the writeBuffer.<br>

<br><b>* Bottom line problem description: Audio out while capturing plays correctly, but playing back the recorded "output.avi" is static taps at approx .25-.5 sec intervals.<br></b><br><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">static void get_audio_frame(int16_t *samples, int frame_size, int nb_channels)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">{</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">    if(!m_audioPackets.isEmpty())</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">    {</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">        AudioPacket first = m_audioPackets.first();</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">        int msecLatency = first.timestamp.msecsTo(QTime::currentTime());</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">    </span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">        qDebug() << "get_audio_frame(): playback: consumed packet, msecLatency:"<<msecLatency<<", buffer size:"<<m_audioPackets.size()<<", packet size:"<<first.data.size();</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">        m_audioPackets.takeFirst();</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">        </span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">        outputDevice->write(first.data);</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">        </span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">        writeBuffer.append(first.data);</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">    }</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">    </span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">        </span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">    if(!writeBuffer.isEmpty())</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">    {</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">        int sz = writeBuffer.size();</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">        char * data = writeBuffer.data();</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">            </span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">        // frame_size*2 becauase 2 bytes = 1 int16_t</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">        int dCounter = qMin(frame_size*2, sz);</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">        </span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">        memcpy(samples, data, dCounter);</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">        </span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">        writeBuffer.remove(0, dCounter);</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">        </span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">        qDebug() << "get_audio_frame(): frame_size:"<<frame_size<<", nb_channels:"<<nb_channels<<", dCounter:"<<dCounter<<", sz:"<<sz;</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">    }</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">    else</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">    {</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">        qDebug() << "get_audio_frame(): ** BUFFER UNDERRUN **";</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">    }</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">}</span><br style="font-family:courier new,monospace"><br><br>-- <br>Josiah Bryan<br>765-215-0511<br><a href="mailto:josiahbryan@gmail.com" target="_blank">josiahbryan@gmail.com</a><br>