<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content="text/html; charset=us-ascii" http-equiv=Content-Type>
<META name=GENERATOR content="MSHTML 9.00.8112.16430"></HEAD>
<BODY>
<DIV dir=ltr align=left><SPAN class=683082707-24112011><FONT color=#0000ff
size=2 face=Arial>Hi Karl!</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=683082707-24112011><FONT color=#0000ff
size=2 face=Arial></FONT></SPAN> </DIV>
<DIV dir=ltr align=left><SPAN class=683082707-24112011><FONT color=#0000ff
size=2 face=Arial>You should always place an audioconvert + audioresample
right before the audiosink, see:</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=683082707-24112011><FONT color=#0000ff
size=2 face=Arial><A
href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good-plugins/html/gst-plugins-good-plugins-directsoundsink.html">http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good-plugins/html/gst-plugins-good-plugins-directsoundsink.html</A></FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=683082707-24112011><FONT color=#0000ff
size=2 face=Arial></FONT></SPAN> </DIV>
<DIV dir=ltr align=left><SPAN class=683082707-24112011><FONT color=#0000ff
size=2 face=Arial>I would remove the audioresample from the first pipeline. In
the 2nd:</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=683082707-24112011><FONT color=#0000ff
size=2 face=Arial></FONT></SPAN> </DIV>
<DIV dir=ltr align=left><SPAN class=683082707-24112011><FONT color=#0000ff
size=2 face=Arial>adder audioconvert audioresample
autosoundsink</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=683082707-24112011><FONT color=#0000ff
size=2 face=Arial></FONT></SPAN> </DIV>
<DIV dir=ltr align=left><SPAN class=683082707-24112011><FONT color=#0000ff
size=2 face=Arial>You can try your pipelines via gst-launch before implementing
them right away-</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=683082707-24112011><FONT color=#0000ff
size=2 face=Arial></FONT></SPAN> </DIV>
<DIV dir=ltr align=left><SPAN class=683082707-24112011><FONT color=#0000ff
size=2 face=Arial>cheers,</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=683082707-24112011><FONT color=#0000ff
size=2 face=Arial></FONT></SPAN> </DIV>
<DIV dir=ltr align=left><SPAN class=683082707-24112011><FONT color=#0000ff
size=2 face=Arial>mat</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=683082707-24112011><FONT color=#0000ff
size=2 face=Arial></FONT></SPAN> </DIV><BR>
<DIV dir=ltr lang=de class=OutlookMessageHeader align=left>
<HR tabIndex=-1>
<FONT size=2 face=Tahoma><B>Von:</B>
gstreamer-devel-bounces+mdodt=xion-medical.com@lists.freedesktop.org
[mailto:gstreamer-devel-bounces+mdodt=xion-medical.com@lists.freedesktop.org]
<B>Im Auftrag von </B>Karl Phillip<BR><B>Gesendet:</B> 23 November 2011
14:00<BR><B>An:</B> gstreamer-devel@lists.freedesktop.org<BR><B>Betreff:</B>
Audio mixing with ADDER results in broken sound<BR></FONT><BR></DIV>
<DIV></DIV>Hi all, <BR><BR>I'm using QtGStreamer-0.10 to play a mp3 file and I'm
having difficulties finding out why the resulting sound is so horrible. I wrote
the smallest application possible to reproduce the problem I'm
facing.<BR><BR>I'm working on a "audio mixer" component that allows you to have
multiple audio players instantiated and running. It'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't deal with 8, 9 audio players simultaneously. So I'm
hoping to make it's job easier by sending it only one audio stream.<BR><BR>Let's
jump into the code! The application below sets up 2 pipelines: the first named
"_ms_pipeline" (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 "pipeline", loads the file from the disk through FILESRC,
decodes it, does some stuff using the following elements: APPSRC > VOLUME
> AUDIOCONVERT > AUDIORESAMPLE > 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 <QtGui/QApplication><BR><BR>#include
<QList><BR>#include <QPointer><BR>#include
<QObject><BR><BR>#include <QGlib/Error><BR>#include
<QGlib/Connect><BR>#include <QGst/Init><BR>#include
<QGst/Bus><BR>#include <QGst/Pipeline><BR>#include
<QGst/Parse><BR>#include <QGst/Message><BR>#include
<QGst/Utils/ApplicationSink><BR>#include
<QGst/Utils/ApplicationSource><BR>#include
<QGst/ElementFactory><BR>#include <QGst/Element><BR>#include
<QGst/Pad><BR>#include <QGst/Bin><BR><BR>#include
<iostream><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->endOfStream();<BR> }<BR><BR>
virtual QGst::FlowReturn newBuffer()<BR>
{<BR>
m_src->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 <<
"Player::onNewDecodePad\n";<BR>
QGst::CapsPtr caps =
pad->caps();<BR> QGst::StructurePtr
structure =
caps->internalStructure(0);<BR> if
(structure->name().contains("audio/x-raw"))
<BR> std::cout
<< "Player::onNewDecodePad
audio/x-raw\n";<BR><BR> QGst::PadPtr
saidaDecoder =
appsink->getStaticPad("sink");<BR>
if (pad->link(saidaDecoder) !=
QGst::PadLinkOk)<BR>
std::cout << "Player::onNewDecodePad: Failed link
!!!\n";<BR><BR> }<BR>};<BR><BR><BR>int main(int argc, char
*argv[])<BR>{<BR> if (argc < 2) <BR>
{<BR> std::cout << "Usage:
qtplayer <file.mp3>\n";<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(&m_src)<BR>{<BR> QGst::init(0,
NULL);<BR><BR> // Master pipeline setup<BR><BR>
_ms_pipeline = QGst::Pipeline::create("mypipe");<BR> if
(!_ms_pipeline)<BR>
{<BR> qDebug() << "MasterSink:
Failed creating pipeline !!!";<BR>
return;<BR> }<BR>
_ms_pipeline->setState(QGst::StateNull);<BR><BR> _ms_adder
= QGst::ElementFactory::make("adder","audiomixer");<BR>
_ms_pipeline->add(_ms_adder);<BR><BR> _ms_output =
QGst::ElementFactory::make("autoaudiosink","audio_out");<BR>
_ms_pipeline->add(_ms_output);<BR><BR> if
(!_ms_adder->link(_ms_output))<BR>
{<BR> qDebug() << "MasterSink:
Failed linking to _output !!!";<BR>
return;<BR> }<BR><BR>
_ms_pipeline->setState(QGst::StateReady);<BR> std::cout
<< "_ms_pipeline: StateReady\n";<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("filesrc");<BR>
filesrc->setProperty("location", filename);<BR>
pipeline->add(filesrc); <BR><BR>
QGst::BinPtr decodebin =
QGst::ElementFactory::make("decodebin2").dynamicCast<QGst::Bin>();<BR>
pipeline->add(decodebin);<BR> if
(!filesrc->link(decodebin))<BR>
{<BR> qDebug() << "Failed:
filesrc > decodebin !!!";<BR>
return;<BR> }<BR><BR> appsink =
QGst::ElementFactory::make("appsink");<BR>
pipeline->add(appsink);<BR><BR>
m_sink.setElement(appsink);<BR><BR> QGst::ElementPtr appsrc =
QGst::ElementFactory::make("appsrc");<BR>
m_src.setElement(appsrc);<BR>
m_src.setFormat(QGst::FormatDefault);<BR><BR>
_ms_pipeline->add(appsrc);<BR><BR> QGst::ElementPtr vol =
QGst::ElementFactory::make("volume");<BR>
vol->setProperty("volume", 0.7);<BR> QGst::ElementPtr
convert = QGst::ElementFactory::make("audioconvert");<BR>
QGst::ElementPtr resample =
QGst::ElementFactory::make("audioresample");<BR><BR>
QGst::ElementPtr filtercaps =
QGst::ElementFactory::make("capsfilter");<BR>
filtercaps->setProperty("caps", QGst::Caps::fromString("audio/x-raw-int,
endianness=(int)1234, channels=(int)1, width=(int)16, depth=(int)16,
signed=(boolean)true, rate=(int)11025"));<BR><BR>
_ms_pipeline->add(vol);<BR>
_ms_pipeline->add(convert);<BR>
_ms_pipeline->add(resample);<BR>
_ms_pipeline->add(filtercaps);<BR><BR> if
(!appsrc->link(vol))<BR>
{<BR> qDebug() << "Failed:
appsrc > vol !!!";<BR>
return;<BR> }<BR><BR> if
(!vol->link(convert))<BR>
{<BR> qDebug() << "Failed:
filesrc > decodebin !!!";<BR>
return;<BR> }<BR><BR> if
(!convert->link(resample))<BR>
{<BR> qDebug() << "Failed:
filesrc > decodebin !!!";<BR>
return;<BR> }<BR><BR> if
(!resample->link(filtercaps))<BR>
{<BR> qDebug() << "Failed:
filesrc > decodebin !!!";<BR>
return;<BR> }<BR><BR> QGst::PadPtr sinkpad =
_ms_adder->getRequestPad("sink%d");<BR> if
(!sinkpad)<BR> {<BR>
qDebug() << "Failed: sinkpad
!!!";<BR>
return;<BR> }<BR><BR> QGst::PadPtr
saidaConverters = filtercaps->getStaticPad("src");<BR> if
(saidaConverters->link(sinkpad) != QGst::PadLinkOk)<BR>
{<BR> qDebug() << "Failed: saida
> sinkpad !!!";<BR>
return;<BR> }<BR><BR>
QGlib::connect(decodebin, "pad-added", this,
&Player::onNewDecodedPad);<BR><BR>
pipeline->setState(QGst::StatePlaying);<BR> std::cout
<< "pipeline: StatePlaying\n";<BR><BR> QGst::State
state;<BR> pipeline->getState(&state, NULL,
0);<BR> std::cout << "pipeline: state is " <<
state << " while playing would be: " << QGst::StatePlaying <<
"\n";<BR><BR><BR> QGst::State ms_state;<BR>
_ms_pipeline->getState(&ms_state, NULL, 0);<BR> if
(ms_state != QGst::StatePlaying)<BR>
{<BR> std::cout <<
"_ms_pipeline: StatePlaying *AGAIN* was: " << ms_state <<
"\n";<BR>
_ms_pipeline->setState(QGst::StateNull);<BR>
_ms_pipeline->setState(QGst::StatePlaying);<BR>
}<BR><BR> _ms_pipeline->getState(&ms_state, NULL,
0);<BR> std::cout << "_ms_pipeline: state is " <<
ms_state << "\n";<BR>}<BR></BODY></HTML>