Hi all, <br><br>I&#39;m using QtGStreamer-0.10 to play a mp3 file and I&#39;m having difficulties finding out why the resulting sound is so horrible. I wrote the smallest application possible to reproduce the problem I&#39;m facing.<br>
<br>I&#39;m working on a &quot;audio mixer&quot; component that allows you to have multiple audio players instantiated and running. It&#39;s job is to mix all audio received by the players and chose to do this task myself because the soundcard I have is terrible and can&#39;t deal with 8, 9 audio players simultaneously. So I&#39;m hoping to make it&#39;s job easier by sending it only one audio stream.<br>
<br>Let&#39;s jump into the code! The application below sets up 2 pipelines: the first named &quot;_ms_pipeline&quot; (as in master pipeline), and its responsible for mixing the audio using only 2 elements: an ADDER linked to AUTOAUDIOSINK. <br>
<br>The second pipeline, named only &quot;pipeline&quot;, loads the file from the disk through FILESRC, decodes it, does some stuff using the following elements: APPSRC &gt; VOLUME &gt; AUDIOCONVERT &gt; AUDIORESAMPLE &gt; CAPSFILTER.<br>
<br>At the end I connect the src pad of CAPSFILTER to a sink pad of the ADDER, then set the state of the pipelines to QGst::StatePlaying to start playing the audio.<br><br>The result is awful.<br><br>#include &lt;QtGui/QApplication&gt;<br>
<br>#include &lt;QList&gt;<br>#include &lt;QPointer&gt;<br>#include &lt;QObject&gt;<br><br>#include &lt;QGlib/Error&gt;<br>#include &lt;QGlib/Connect&gt;<br>#include &lt;QGst/Init&gt;<br>#include &lt;QGst/Bus&gt;<br>#include &lt;QGst/Pipeline&gt;<br>
#include &lt;QGst/Parse&gt;<br>#include &lt;QGst/Message&gt;<br>#include &lt;QGst/Utils/ApplicationSink&gt;<br>#include &lt;QGst/Utils/ApplicationSource&gt;<br>#include &lt;QGst/ElementFactory&gt;<br>#include &lt;QGst/Element&gt;<br>
#include &lt;QGst/Pad&gt;<br>#include &lt;QGst/Bin&gt;<br><br>#include &lt;iostream&gt;<br><br>QGst::PipelinePtr _ms_pipeline;<br>QGst::ElementPtr _ms_adder;<br>QGst::ElementPtr _ms_output;<br><br>QGst::ElementPtr appsink;<br>
<br>class MySink : public QGst::Utils::ApplicationSink<br>{<br>public:<br>    MySink(QGst::Utils::ApplicationSource *src)<br>    : QGst::Utils::ApplicationSink(), m_src(src) {}<br><br>protected:<br>    virtual void eos()<br>
    {<br>        m_src-&gt;endOfStream();<br>    }<br><br>    virtual QGst::FlowReturn newBuffer()<br>    {<br>        m_src-&gt;pushBuffer(pullBuffer());<br>        return QGst::FlowOk;<br>    }<br><br>private:<br>    QGst::Utils::ApplicationSource *m_src;<br>
};<br><br><br>class Player : QObject<br>{<br>public:<br>    Player(const char* filename);<br>    ~Player() {};<br><br>    MySink m_sink; <br>    QGst::Utils::ApplicationSource m_src;<br><br>    void onNewDecodedPad(QGst::PadPtr pad)    <br>
    {<br>        std::cout &lt;&lt; &quot;Player::onNewDecodePad\n&quot;;<br>        QGst::CapsPtr caps = pad-&gt;caps();<br>        QGst::StructurePtr structure = caps-&gt;internalStructure(0);<br>        if (structure-&gt;name().contains(&quot;audio/x-raw&quot;)) <br>
            std::cout &lt;&lt; &quot;Player::onNewDecodePad audio/x-raw\n&quot;;<br><br>        QGst::PadPtr saidaDecoder = appsink-&gt;getStaticPad(&quot;sink&quot;);<br>        if (pad-&gt;link(saidaDecoder) != QGst::PadLinkOk)<br>
            std::cout &lt;&lt; &quot;Player::onNewDecodePad: Failed link !!!\n&quot;;<br><br>    }<br>};<br><br><br>int main(int argc, char *argv[])<br>{<br>    if (argc &lt; 2) <br>    {<br>        std::cout &lt;&lt; &quot;Usage: qtplayer &lt;file.mp3&gt;\n&quot;;<br>
        return -1;<br>    }<br><br>    QApplication app(argc, argv);<br><br>    Player player(argv[1]);<br><br>    return app.exec();<br>}<br><br><br>Player::Player(const char* filename)<br>: m_sink(&amp;m_src)<br>{<br>    QGst::init(0, NULL);<br>
<br>   // Master pipeline setup<br><br>    _ms_pipeline = QGst::Pipeline::create(&quot;mypipe&quot;);<br>    if (!_ms_pipeline)<br>    {<br>        qDebug() &lt;&lt; &quot;MasterSink: Failed creating pipeline !!!&quot;;<br>
        return;<br>    }<br>    _ms_pipeline-&gt;setState(QGst::StateNull);<br><br>    _ms_adder = QGst::ElementFactory::make(&quot;adder&quot;,&quot;audiomixer&quot;);<br>    _ms_pipeline-&gt;add(_ms_adder);<br><br>    _ms_output = QGst::ElementFactory::make(&quot;autoaudiosink&quot;,&quot;audio_out&quot;);<br>
    _ms_pipeline-&gt;add(_ms_output);<br><br>    if (!_ms_adder-&gt;link(_ms_output))<br>    {<br>        qDebug() &lt;&lt; &quot;MasterSink: Failed linking to _output !!!&quot;;<br>        return;<br>    }<br><br>    _ms_pipeline-&gt;setState(QGst::StateReady);<br>
    std::cout &lt;&lt; &quot;_ms_pipeline: StateReady\n&quot;;<br><br><br>    // This 2nd pipeline loads the file, decodes it and sends the audio stream to the master pipeline <br><br>    QGst::PipelinePtr pipeline = QGst::Pipeline::create();<br>
<br>    QGst::ElementPtr filesrc = QGst::ElementFactory::make(&quot;filesrc&quot;);<br>    filesrc-&gt;setProperty(&quot;location&quot;, filename);<br>    pipeline-&gt;add(filesrc);    <br><br>    QGst::BinPtr decodebin = QGst::ElementFactory::make(&quot;decodebin2&quot;).dynamicCast&lt;QGst::Bin&gt;();<br>
    pipeline-&gt;add(decodebin);<br>    if (!filesrc-&gt;link(decodebin))<br>    {<br>        qDebug() &lt;&lt; &quot;Failed: filesrc &gt; decodebin !!!&quot;;<br>        return;<br>    }<br><br>    appsink = QGst::ElementFactory::make(&quot;appsink&quot;);<br>
    pipeline-&gt;add(appsink);<br><br>    m_sink.setElement(appsink);<br><br>    QGst::ElementPtr appsrc = QGst::ElementFactory::make(&quot;appsrc&quot;);<br>    m_src.setElement(appsrc);<br>    m_src.setFormat(QGst::FormatDefault);<br>
<br>    _ms_pipeline-&gt;add(appsrc);<br><br>    QGst::ElementPtr vol = QGst::ElementFactory::make(&quot;volume&quot;);<br>    vol-&gt;setProperty(&quot;volume&quot;, 0.7);<br>    QGst::ElementPtr convert = QGst::ElementFactory::make(&quot;audioconvert&quot;);<br>
    QGst::ElementPtr resample = QGst::ElementFactory::make(&quot;audioresample&quot;);<br><br>    QGst::ElementPtr filtercaps = QGst::ElementFactory::make(&quot;capsfilter&quot;);<br>    filtercaps-&gt;setProperty(&quot;caps&quot;, QGst::Caps::fromString(&quot;audio/x-raw-int, endianness=(int)1234, channels=(int)1, width=(int)16, depth=(int)16, signed=(boolean)true, rate=(int)11025&quot;));<br>
<br>    _ms_pipeline-&gt;add(vol);<br>    _ms_pipeline-&gt;add(convert);<br>    _ms_pipeline-&gt;add(resample);<br>    _ms_pipeline-&gt;add(filtercaps);<br><br>    if (!appsrc-&gt;link(vol))<br>    {<br>        qDebug() &lt;&lt; &quot;Failed: appsrc &gt; vol !!!&quot;;<br>
        return;<br>    }<br><br>    if (!vol-&gt;link(convert))<br>    {<br>        qDebug() &lt;&lt; &quot;Failed: filesrc &gt; decodebin !!!&quot;;<br>        return;<br>    }<br><br>    if (!convert-&gt;link(resample))<br>
    {<br>        qDebug() &lt;&lt; &quot;Failed: filesrc &gt; decodebin !!!&quot;;<br>        return;<br>    }<br><br>    if (!resample-&gt;link(filtercaps))<br>    {<br>        qDebug() &lt;&lt; &quot;Failed: filesrc &gt; decodebin !!!&quot;;<br>
        return;<br>    }<br><br>    QGst::PadPtr sinkpad = _ms_adder-&gt;getRequestPad(&quot;sink%d&quot;);<br>    if (!sinkpad)<br>    {<br>        qDebug() &lt;&lt; &quot;Failed: sinkpad !!!&quot;;<br>        return;<br>
    }<br><br>    QGst::PadPtr saidaConverters = filtercaps-&gt;getStaticPad(&quot;src&quot;);<br>    if (saidaConverters-&gt;link(sinkpad) != QGst::PadLinkOk)<br>    {<br>        qDebug() &lt;&lt; &quot;Failed: saida &gt; sinkpad !!!&quot;;<br>
        return;<br>    }<br><br>    QGlib::connect(decodebin, &quot;pad-added&quot;, this, &amp;Player::onNewDecodedPad);<br><br>    pipeline-&gt;setState(QGst::StatePlaying);<br>    std::cout &lt;&lt; &quot;pipeline: StatePlaying\n&quot;;<br>
<br>    QGst::State state;<br>    pipeline-&gt;getState(&amp;state, NULL, 0);<br>    std::cout &lt;&lt; &quot;pipeline: state is &quot; &lt;&lt; state &lt;&lt; &quot; while playing would be: &quot; &lt;&lt; QGst::StatePlaying &lt;&lt; &quot;\n&quot;;<br>
<br><br>    QGst::State ms_state;<br>    _ms_pipeline-&gt;getState(&amp;ms_state, NULL, 0);<br>    if (ms_state != QGst::StatePlaying)<br>    {<br>        std::cout &lt;&lt; &quot;_ms_pipeline: StatePlaying *AGAIN* was: &quot; &lt;&lt; ms_state &lt;&lt; &quot;\n&quot;;<br>
        _ms_pipeline-&gt;setState(QGst::StateNull);<br>        _ms_pipeline-&gt;setState(QGst::StatePlaying);<br>    }<br><br>    _ms_pipeline-&gt;getState(&amp;ms_state, NULL, 0);<br>    std::cout &lt;&lt; &quot;_ms_pipeline: state is &quot; &lt;&lt; ms_state &lt;&lt; &quot;\n&quot;;<br>
}<br>