[libav-api] Convert char* to int16_t* for use in get_audio_frame() in output-example2.c

Josiah Bryan josiahbryan at gmail.com
Thu Jul 5 21:51:50 CEST 2012


On Wed, Jul 4, 2012 at 3:12 PM, Anton Khirnov <anton at khirnov.net> wrote:

>
> Hi,
> could you provide more complete code samples. Like what does your
> get_audio_frame() look like (did you do any modifications to it?) or how
> exactly are you calling it.
>
> --
> Anton Khirnov
>

Sure, no problem.

Full code download here:
*http://corp.productiveconcepts.com/qt-libav-recording-test-20120705.tar.gz*

*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.)
*
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.

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);"

And, yes - I made *extensive* modifications to get_audio_frame() to try to
get it tied together with Qt's audio code.

Since it's short, here's the get_audio_frame() code, below.

*A quick walkthru:*

* 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.

* 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.

* 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.

** 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.
*

static void get_audio_frame(int16_t *samples, int frame_size, int
nb_channels)
{
    if(!m_audioPackets.isEmpty())
    {
        AudioPacket first = m_audioPackets.first();
        int msecLatency = first.timestamp.msecsTo(QTime::currentTime());

        qDebug() << "get_audio_frame(): playback: consumed packet,
msecLatency:"<<msecLatency<<", buffer size:"<<m_audioPackets.size()<<",
packet size:"<<first.data.size();
        m_audioPackets.takeFirst();

        outputDevice->write(first.data);

        writeBuffer.append(first.data);
    }


    if(!writeBuffer.isEmpty())
    {
        int sz = writeBuffer.size();
        char * data = writeBuffer.data();

        // frame_size*2 becauase 2 bytes = 1 int16_t
        int dCounter = qMin(frame_size*2, sz);

        memcpy(samples, data, dCounter);

        writeBuffer.remove(0, dCounter);

        qDebug() << "get_audio_frame(): frame_size:"<<frame_size<<",
nb_channels:"<<nb_channels<<", dCounter:"<<dCounter<<", sz:"<<sz;
    }
    else
    {
        qDebug() << "get_audio_frame(): ** BUFFER UNDERRUN **";
    }
}


-- 
Josiah Bryan
765-215-0511
josiahbryan at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.libav.org/pipermail/libav-api/attachments/20120705/67a059b6/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: recorder.cpp
Type: text/x-c++src
Size: 21295 bytes
Desc: not available
URL: <http://lists.libav.org/pipermail/libav-api/attachments/20120705/67a059b6/attachment-0001.cpp>


More information about the libav-api mailing list