[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:

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

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

** 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
        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();



        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;
        qDebug() << "get_audio_frame(): ** BUFFER UNDERRUN **";

Josiah Bryan
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