<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>speex &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://en.wordpress.com/tag/speex/</link>
	<description>Feed of posts on WordPress.com tagged "speex"</description>
	<pubDate>Tue, 01 Dec 2009 00:14:29 +0000</pubDate>

	<generator>http://en.wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[Testing portaudio and speex - part 4]]></title>
<link>http://slworkthings.wordpress.com/2009/11/11/testing-portaudio-and-speex-part-4/</link>
<pubDate>Wed, 11 Nov 2009 00:35:57 +0000</pubDate>
<dc:creator>slworkthings</dc:creator>
<guid>http://slworkthings.wordpress.com/2009/11/11/testing-portaudio-and-speex-part-4/</guid>
<description><![CDATA[Continue. AudioEngine header file: #ifndef _AUDIOENGINE_H_ #define _AUDIOENGINE_H_ #include &#8220;m]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Continue.</p>
<p>AudioEngine header file:<br />
#ifndef _AUDIOENGINE_H_<br />
#define _AUDIOENGINE_H_</p>
<p>#include &#8220;mysocket.h&#8221;<br />
#include &#8220;portaudio.h&#8221;<br />
#include &#8220;san_speex.h&#8221;<br />
#include &#60;qwidget.h&#62;</p>
<p>#define SAMPLE_RATE  16000<br />
#define FRAMES_PER_BUFFER 320<br />
#define PA_SAMPLE_TYPE  paInt16<br />
typedef short SAMPLE;<br />
#define SAMPLE_SILENCE  (0)<br />
#define NUM_CHANNELS    1<br />
class AudioEngine;<br />
typedef struct<br />
{<br />
    SanSpeexEnc     speexenc;<br />
    SAMPLE          recordbuffer[FRAMES_PER_BUFFER * NUM_CHANNELS];<br />
    char            encodedBufPlus8[FRAMES_PER_BUFFER * NUM_CHANNELS * 2 ];<br />
    SanSpeexDec     speexdec;<br />
    SAMPLE          playbackbuffer[FRAMES_PER_BUFFER * NUM_CHANNELS];<br />
    AudioEngine    *obj;<br />
} paTestData;<br />
//============================================<br />
class AudioEngine : public QWidget<br />
{<br />
    Q_OBJECT<br />
public:<br />
    AudioEngine();<br />
    virtual ~AudioEngine();</p>
<p>    void recvPlaybackDataIn(const QByteArray&#38; ba);<br />
    void setSelfLoop(bool flag);<br />
    bool isSelfLoop() const { return m_isSelfLoop; }<br />
protected:<br />
    virtual void closeEvent(QCloseEvent *);</p>
<p>private slots:<br />
    void slotReceivedData(const QByteArray&#38;);<br />
    void slotReceivedHandshake(const QString&#38; hisId);</p>
<p>private:<br />
    static int s_recordCallback(const void *inputBuffer, void *outputBuffer,<br />
                                unsigned long framesPerBuffer,<br />
                                const PaStreamCallbackTimeInfo* timeInfo,<br />
                                PaStreamCallbackFlags statusFlags,<br />
                                void *userData);<br />
    static int s_playCallback(const void *inputBuffer, void *outputBuffer,<br />
                              unsigned long framesPerBuffer,<br />
                              const PaStreamCallbackTimeInfo* timeInfo,<br />
                              PaStreamCallbackFlags statusFlags,<br />
                              void *userData);<br />
    static int s_loopCallback(const void *inputBuffer, void *outputBuffer,<br />
                              unsigned long framesPerBuffer,<br />
                              const PaStreamCallbackTimeInfo* timeInfo,<br />
                              PaStreamCallbackFlags statusFlags,<br />
                              void *userData);</p>
<p>    bool initPa();<br />
    bool unInitPa();<br />
    bool startPaRecorder(int id);<br />
    bool startPaPlayback(int id);<br />
    bool stopPaRecorder();<br />
    bool stopPaPlayback();<br />
    bool startPaRecorderPlaybackLoop(int inputId, int outputId);<br />
    bool stopPaRecorderPlaybackLoop();</p>
<p>    void sendRecordDataOut(char *buf, int len);</p>
<p>private:<br />
    MyServerSocket    *m_serverSocket;<br />
    QString            m_recorderId;<br />
    QString            m_playbackId;</p>
<p>    PaStream          *m_streamIn, *m_streamOut;<br />
    PaError            m_errIn, m_errOut;<br />
    int                m_inputId, m_outputId;</p>
<p>    paTestData         m_data;<br />
    bool               m_isSelfLoop;<br />
};</p>
<p>#endif // _AUDIOENGINE_H_</p>
<p> AudioEngine source file:</p>
<p>#include &#8220;audioengine.h&#8221;<br />
#include &#60;qapplication.h&#62;<br />
#include &#60;windows.h&#62;<br />
//#include &#60;mmddk.h&#62;</p>
<p>//===================================<br />
AudioEngine::AudioEngine()<br />
            :QWidget(),<br />
             m_serverSocket(0),<br />
             m_recorderId(QString::null),<br />
             m_playbackId(QString::null),<br />
             m_streamIn(0),<br />
             m_streamOut(0),<br />
             m_errIn(paNoError),<br />
             m_errOut(paNoError),<br />
             m_inputId(-1),<br />
             m_outputId(-1),<br />
             m_isSelfLoop(true)<br />
{<br />
    qDebug(&#8220;AE ctor&#8221;);<br />
    m_serverSocket = new MyServerSocket();<br />
    connect(m_serverSocket, SIGNAL(fireReceivedData(const QByteArray&#38;)),<br />
                            SLOT(slotReceivedData(const QByteArray&#38;)));<br />
    connect(m_serverSocket, SIGNAL(fireReceivedHandshake(const QString&#38;)),<br />
                            SLOT(slotReceivedHandshake(const QString&#38;)));<br />
    qDebug(&#8220;m_serverSocket port = %d&#8221;, m_serverSocket-&#62;port());</p>
<p>    resize(100, 100);<br />
    move(0, 0);<br />
    hide();</p>
<p>    m_data.obj = this;<br />
    m_data.speexdec.setSanSpeexEnc(&#38;m_data.speexenc);<br />
    initPa();<br />
}</p>
<p>AudioEngine::~AudioEngine()<br />
{<br />
    qDebug(&#8220;AE dtor&#8221;);<br />
    delete m_serverSocket;<br />
    m_serverSocket = 0;<br />
    unInitPa();<br />
}</p>
<p>void AudioEngine::closeEvent(QCloseEvent *)<br />
{<br />
    qDebug(&#8220;AE::closeEvent&#8221;);<br />
    qApp-&#62;exit(0);<br />
}</p>
<p>void AudioEngine::slotReceivedData(const QByteArray&#38; ba)<br />
{<br />
    qDebug(&#8220;AE::slotRecvData = %d&#8221;, ba.size());<br />
    const char *data = ba.data();<br />
    if (ba.size() &#62;= 4 &#38;&#38; data[0] == &#8216;c&#8217; &#38;&#38; data[1] == &#8216;m&#8217; &#38;&#38; data[2] == &#8216;d&#8217;)<br />
    {<br />
        char cmd = data[3];<br />
        switch (cmd)<br />
        {<br />
        case &#8216;1&#8242;: //return device list;   dev1\ndev2\n&#8230;<br />
            {<br />
                QString devList(ba);<br />
                devList = devList.mid(4);<br />
                qDebug(&#8220;1. DevList = &#8221; + devList);<br />
            }<br />
            break;<br />
        case &#8216;2&#8242;: //set recorder device;  devname<br />
            {<br />
                QString devName(ba);<br />
                devName = devName.mid(4);<br />
                qDebug(&#8220;2. RecorderDevice = &#8221; + devName);<br />
                m_inputId = devName.toInt();<br />
            }<br />
            break;<br />
        case &#8216;3&#8242;: //set playback device; devname<br />
            {<br />
                QString devName(ba);<br />
                devName = devName.mid(4);<br />
                qDebug(&#8220;3. PlaybackDevice = &#8221; + devName);<br />
                m_outputId = devName.toInt();<br />
            }<br />
            break;<br />
        case &#8216;4&#8242;: //start recorder<br />
            qDebug(&#8220;4. Start Recording&#8221;);<br />
            if (!m_isSelfLoop)<br />
            {<br />
                if (m_inputId != -1 &#38;&#38; m_streamIn == 0)<br />
                    startPaRecorder(m_inputId);<br />
            }<br />
            else<br />
            {<br />
                if (m_inputId != -1 &#38;&#38; m_outputId != -1 &#38;&#38; m_streamIn == 0)<br />
                    startPaRecorderPlaybackLoop(m_inputId, m_outputId);<br />
            }<br />
            break;<br />
        case &#8216;5&#8242;: //start playback<br />
            qDebug(&#8220;5. Start Playback&#8221;);<br />
            if (!m_isSelfLoop)<br />
            {<br />
                if (m_outputId != -1 &#38;&#38; m_streamOut == 0)<br />
                    startPaPlayback(m_outputId);<br />
            }<br />
            else<br />
            {<br />
                if (m_inputId != -1 &#38;&#38; m_outputId != -1 &#38;&#38; m_streamIn == 0)<br />
                    startPaRecorderPlaybackLoop(m_inputId, m_outputId);<br />
            }<br />
            break;<br />
        case &#8216;6&#8242;: //stop recorder<br />
            qDebug(&#8220;6. Stop Recording&#8221;);<br />
            if (!m_isSelfLoop)<br />
                stopPaRecorder();<br />
            else<br />
                stopPaRecorderPlaybackLoop();<br />
            break;<br />
        case &#8216;7&#8242;: //stop playback<br />
            qDebug(&#8220;7. Stop Playback&#8221;);<br />
            if (!m_isSelfLoop)<br />
                stopPaPlayback();<br />
            else<br />
                stopPaRecorderPlaybackLoop();<br />
            break;<br />
        case &#8216;Q&#8217;: //totally exit<br />
            qDebug(&#8220;Q. Quit&#8221;);<br />
            if (m_serverSocket)<br />
                m_serverSocket-&#62;stop();<br />
            show();<br />
            break;<br />
        default:<br />
            break;<br />
        }//switch()<br />
    }//&#8221;cmd&#8221;<br />
    else //binary<br />
    {<br />
    }//binary<br />
}//slotReceivedData()</p>
<p>void AudioEngine::slotReceivedHandshake(const QString&#38; hisId)<br />
{<br />
    qDebug(&#8220;AE::slotRecvHandshake = &#8221; + hisId);<br />
    if (hisId == &#8220;recorder&#8221;)<br />
        m_recorderId = hisId;<br />
    else if (hisId == &#8220;playback&#8221;)<br />
        m_playbackId = hisId;<br />
}//slotReceivedHandshake()</p>
<p>int AudioEngine::s_recordCallback(const void *inputBuffer, void *outputBuffer,<br />
                                  unsigned long framesPerBuffer,<br />
                                  const PaStreamCallbackTimeInfo* timeInfo,<br />
                                  PaStreamCallbackFlags statusFlags,<br />
                                  void *userData)<br />
{<br />
    paTestData *data = (paTestData*)userData;<br />
    const SAMPLE *rptr = (const SAMPLE*)inputBuffer;<br />
    SAMPLE *wptr = data-&#62;recordbuffer;<br />
    long framesToCalc;<br />
    framesToCalc = framesPerBuffer;<br />
    long i;<br />
    int finished = paContinue;<br />
    bool isSelfLoop = data-&#62;obj-&#62;isSelfLoop();<br />
   <br />
    (void) outputBuffer; /* Prevent unused variable warnings. */<br />
    (void) timeInfo;<br />
    (void) statusFlags;<br />
    (void) userData;</p>
<p>    if( inputBuffer == NULL )<br />
    {<br />
        for( i=0; i&#60;framesToCalc; i++ )<br />
        {<br />
            *wptr++ = SAMPLE_SILENCE;<br />
            if (NUM_CHANNELS == 2)<br />
                *wptr++ = SAMPLE_SILENCE;<br />
        }<br />
    }<br />
    else<br />
    {<br />
        for( i=0; i&#60;framesToCalc; i++ )<br />
        {<br />
            *wptr++ = *rptr++;<br />
            if (NUM_CHANNELS == 2)<br />
                *wptr++ = *rptr++;<br />
        }<br />
    }</p>
<p>    int encSizePlus8 = data-&#62;speexenc.encode(data-&#62;recordbuffer, data-&#62;encodedBufPlus8);<br />
    if (encSizePlus8 &#62; 0)<br />
    {<br />
        int encSizePlus4 = ((int *)data-&#62;encodedBufPlus8)[0];</p>
<p>        //if (!isSelfLoop)<br />
        {<br />
            //send out encodedBufPlus8 to spydonk<br />
            data-&#62;obj-&#62;sendRecordDataOut(data-&#62;encodedBufPlus8, encSizePlus8);<br />
        }</p>
<p>        /*<br />
        if (isSelfLoop)<br />
        {<br />
            //when seedonk receiving some audio buf from server, call following line<br />
            data-&#62;speexdec.put(data-&#62;encodedBufPlus8+4, encSizePlus4);<br />
        }<br />
        */<br />
    }</p>
<p>    return finished;<br />
}//s_recordCallback()</p>
<p>int AudioEngine::s_playCallback(const void *inputBuffer, void *outputBuffer,<br />
                                unsigned long framesPerBuffer,<br />
                                const PaStreamCallbackTimeInfo* timeInfo,<br />
                                PaStreamCallbackFlags statusFlags,<br />
                                void *userData)<br />
{<br />
    paTestData *data = (paTestData*)userData;<br />
    SAMPLE *rptr = data-&#62;playbackbuffer;<br />
    SAMPLE *wptr = (SAMPLE*)outputBuffer;<br />
    int finished = paContinue;<br />
    unsigned int framesLeft = 0;<br />
    int i;<br />
    bool isSelfLoop = data-&#62;obj-&#62;isSelfLoop();</p>
<p>    data-&#62;speexdec.get(rptr);<br />
    framesLeft = framesPerBuffer;</p>
<p>    (void) inputBuffer; /* Prevent unused variable warnings. */<br />
    (void) timeInfo;<br />
    (void) statusFlags;<br />
    (void) userData;</p>
<p>    for( i=0; i&#60;framesPerBuffer; i++ )<br />
    {<br />
        *wptr++ = *rptr++;<br />
        if (NUM_CHANNELS == 2)<br />
            *wptr++ = *rptr++;<br />
    }</p>
<p>    rptr = data-&#62;playbackbuffer;<br />
    data-&#62;speexdec.afterPlayback(rptr, true);</p>
<p>    return finished;<br />
}//s_playCallback()</p>
<p>int AudioEngine::s_loopCallback(const void *inputBuffer, void *outputBuffer,<br />
                                unsigned long framesPerBuffer,<br />
                                const PaStreamCallbackTimeInfo* timeInfo,<br />
                                PaStreamCallbackFlags statusFlags,<br />
                                void *userData)<br />
{<br />
    paTestData *data = (paTestData*)userData;<br />
    const SAMPLE *rptr = (const SAMPLE*)inputBuffer;<br />
    SAMPLE *wptr = (SAMPLE*)outputBuffer;<br />
    SAMPLE *prevPlayPtr = data-&#62;playbackbuffer;<br />
    long framesToCalc;<br />
    framesToCalc = framesPerBuffer;<br />
    long i;<br />
    int finished = paContinue;<br />
   <br />
    (void) outputBuffer; /* Prevent unused variable warnings. */<br />
    (void) timeInfo;<br />
    (void) statusFlags;<br />
    (void) userData;</p>
<p>    //data-&#62;speexenc.playbackEcho(prevPlayPtr, true);</p>
<p>    if( inputBuffer == NULL )<br />
    {<br />
        for( i=0; i&#60;framesToCalc; i++ )<br />
        {<br />
            *wptr++ = SAMPLE_SILENCE;<br />
            //*prevPlayPtr++ = SAMPLE_SILENCE;<br />
            if (NUM_CHANNELS == 2)<br />
            {<br />
                *wptr++ = SAMPLE_SILENCE;<br />
                //*prevPlayPtr++ = SAMPLE_SILENCE;<br />
            }<br />
        }<br />
        return 0;<br />
    }<br />
    else<br />
    {<br />
        for( i=0; i&#60;framesToCalc; i++ )<br />
        {<br />
            *wptr++ = *rptr;<br />
            //*prevPlayPtr++ = *rptr;<br />
            rptr++;<br />
            if (NUM_CHANNELS == 2)<br />
            {<br />
                *wptr++ = *rptr;<br />
                //*prevPlayPtr++ = *rptr;<br />
                rptr++;<br />
            }<br />
        }<br />
    }</p>
<p>    //data-&#62;speexenc.captureEcho(wptr);<br />
    data-&#62;speexenc.captureEcho(wptr, prevPlayPtr);<br />
    for (i=0; i&#60;framesToCalc; i++)<br />
    {<br />
        *prevPlayPtr++ = *wptr++;<br />
    }</p>
<p>    return finished;<br />
}//s_loopCallback()<br />
bool AudioEngine::initPa()<br />
{<br />
    PaError err = Pa_Initialize();<br />
    if (err == paNoError)<br />
    {<br />
        int numDevices = Pa_GetDeviceCount();<br />
        int inputId, outputId;<br />
        int prevHostApi = -1;<br />
        for(int id=0; id&#60;numDevices; id++)            /* Iterate through all devices. */<br />
        {<br />
            const PaDeviceInfo *pdi = Pa_GetDeviceInfo(id);<br />
            if (prevHostApi != pdi-&#62;hostApi)<br />
            {<br />
                const PaHostApiInfo *info = Pa_GetHostApiInfo(pdi-&#62;hostApi);<br />
                qDebug(&#8220;=== HostApi, %d, type=%d, name=%s ====&#8221;, pdi-&#62;hostApi, info-&#62;type, info-&#62;name);<br />
                qDebug(&#8220;=== def I=%d, defO=%d ====&#8221;, info-&#62;defaultInputDevice, info-&#62;defaultOutputDevice);</p>
<p>                prevHostApi = pdi-&#62;hostApi;</p>
<p>            }<br />
            qDebug(&#8220;[%d]=[%s], IChs=%d, OChs=%d&#8221;,<br />
                               id, pdi-&#62;name,<br />
                               pdi-&#62;maxInputChannels,<br />
                               pdi-&#62;maxOutputChannels);</p>
<p>//#define DRV_RESERVED           0&#215;0800<br />
//#define DRV_QUERYDEVICEINTERFACE     (DRV_RESERVED + 12)<br />
//#define DRV_QUERYDEVICEINTERFACESIZE (DRV_RESERVED + 13)</p>
<p>            /*<br />
            if (pdi-&#62;maxInputChannels &#62; 0)<br />
            {<br />
                DWORD pathSize = 0;<br />
                if (waveInMessage((HWAVEIN)id, 0&#215;0800+13,<br />
                                   (DWORD_PTR)&#38;pathSize, 0) != MMSYSERR_NOERROR)<br />
                {<br />
                    qDebug(&#8220;**** pathSize = %d&#8221;, pathSize);<br />
                    char *path = new char[pathSize];<br />
                    memset(path, 0, pathSize);<br />
                    if (waveInMessage((HWAVEIN)id, 0&#215;0800+12,<br />
                                       (DWORD_PTR)path, sizeof(path)) != MMSYSERR_NOERROR)<br />
                    {<br />
                        qDebug(&#8220;**** path = %s&#8221;, path);<br />
                    }<br />
                    delete [] path;<br />
                }<br />
                else<br />
                    qDebug(&#8220;**** ERROR %d&#8221;, id);<br />
            }<br />
            */<br />
        }<br />
    }<br />
    qDebug(&#8220;======================================&#8221;);<br />
    return (err == paNoError);<br />
}</p>
<p>bool AudioEngine::unInitPa()<br />
{<br />
    if (m_streamIn)<br />
        Pa_CloseStream(m_streamIn);<br />
    m_streamIn = 0;<br />
    if (m_streamOut)<br />
        Pa_CloseStream(m_streamOut);<br />
    m_streamOut = 0;</p>
<p>    Pa_Terminate();<br />
    return true;<br />
}</p>
<p>bool AudioEngine::startPaRecorder(int inputId)<br />
{<br />
    PaStreamParameters  inputParameters;</p>
<p>    inputParameters.device = inputId;<br />
    inputParameters.channelCount = NUM_CHANNELS;<br />
    inputParameters.sampleFormat = PA_SAMPLE_TYPE;<br />
    inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputId)-&#62;defaultLowInputLatency;<br />
    inputParameters.hostApiSpecificStreamInfo = NULL;<br />
    qDebug(&#8220;Input Device = [%s], latency = %f&#8221;, Pa_GetDeviceInfo(inputId)-&#62;name, inputParameters.suggestedLatency);</p>
<p>    /* Record some audio. &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; */<br />
    m_errIn = Pa_OpenStream(&#38;m_streamIn,<br />
                            &#38;inputParameters,<br />
                            NULL,                  /* &#38;outputParameters, */<br />
                            SAMPLE_RATE,<br />
                            FRAMES_PER_BUFFER*NUM_CHANNELS,<br />
                            paClipOff&#124;paDitherOff,      /* we won&#8217;t output out of range samples so don&#8217;t bother clipping them */<br />
                            AudioEngine::s_recordCallback,<br />
                            &#38;m_data);<br />
    if(m_errIn != paNoError)<br />
        return false;</p>
<p>    m_errIn = Pa_StartStream(m_streamIn);<br />
    if(m_errIn != paNoError)<br />
        return false;<br />
    qDebug(&#8220;Now recording!!&#8221;);<br />
    return true;<br />
}//startPaRecorder()</p>
<p>bool AudioEngine::startPaPlayback(int outputId)<br />
{<br />
    PaStreamParameters  outputParameters;</p>
<p>    outputParameters.device = outputId;<br />
    outputParameters.channelCount = NUM_CHANNELS;<br />
    outputParameters.sampleFormat =  PA_SAMPLE_TYPE;<br />
    outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputId)-&#62;defaultLowOutputLatency;<br />
    outputParameters.hostApiSpecificStreamInfo = NULL;<br />
    qDebug(&#8220;Output Device = [%s], latency = %f&#8221;, Pa_GetDeviceInfo(outputId)-&#62;name, outputParameters.suggestedLatency);</p>
<p>    qDebug(&#8220;Begin playback.&#8221;);<br />
    m_errOut = Pa_OpenStream(&#38;m_streamOut,<br />
                             NULL, /* no input */<br />
                             &#38;outputParameters,<br />
                             SAMPLE_RATE,<br />
                             FRAMES_PER_BUFFER*NUM_CHANNELS,<br />
                             paClipOff&#124;paDitherOff,      /* we won&#8217;t output out of range samples so don&#8217;t bother clipping them */<br />
                             AudioEngine::s_playCallback,<br />
                             &#38;m_data);<br />
    if(m_errOut != paNoError)<br />
        return false;</p>
<p>    m_errOut = Pa_StartStream(m_streamOut);<br />
    if(m_errOut != paNoError )<br />
        return false;<br />
    return true;<br />
}//startPaPlayback()</p>
<p>bool AudioEngine::startPaRecorderPlaybackLoop(int inputId, int outputId)<br />
{<br />
    if (m_streamIn != 0) //already started<br />
        return true;</p>
<p>    PaStreamParameters  inputParameters;<br />
    PaStreamParameters  outputParameters;</p>
<p>    inputParameters.device = inputId;<br />
    inputParameters.channelCount = NUM_CHANNELS;<br />
    inputParameters.sampleFormat = PA_SAMPLE_TYPE;<br />
    inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputId)-&#62;defaultLowInputLatency;<br />
    inputParameters.hostApiSpecificStreamInfo = NULL;<br />
    qDebug(&#8220;Input Device = [%s], latency = %f&#8221;, Pa_GetDeviceInfo(inputId)-&#62;name, inputParameters.suggestedLatency);<br />
    outputParameters.device = outputId;<br />
    outputParameters.channelCount = NUM_CHANNELS;<br />
    outputParameters.sampleFormat =  PA_SAMPLE_TYPE;<br />
    outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputId)-&#62;defaultLowOutputLatency;<br />
    outputParameters.hostApiSpecificStreamInfo = NULL;<br />
    qDebug(&#8220;Output Device = [%s], latency = %f&#8221;, Pa_GetDeviceInfo(outputId)-&#62;name, outputParameters.suggestedLatency);</p>
<p>    /* RecordPlayback Loop some audio. &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; */<br />
    m_errIn = Pa_OpenStream(&#38;m_streamIn,<br />
                            &#38;inputParameters,<br />
                            &#38;outputParameters,<br />
                            SAMPLE_RATE,<br />
                            FRAMES_PER_BUFFER*NUM_CHANNELS,<br />
                            paClipOff&#124;paDitherOff,      /* we won&#8217;t output out of range samples so don&#8217;t bother clipping them */<br />
                            AudioEngine::s_loopCallback,<br />
                            &#38;m_data);<br />
    if(m_errIn != paNoError)<br />
        return false;</p>
<p>    m_errIn = Pa_StartStream(m_streamIn);<br />
    if(m_errIn != paNoError)<br />
        return false;<br />
    qDebug(&#8220;Now looping!!&#8221;);<br />
    return true;<br />
}//startPaRecorderPlaybackLoop()</p>
<p>bool AudioEngine::stopPaRecorder()<br />
{<br />
    if (m_streamIn)<br />
        Pa_CloseStream(m_streamIn);<br />
    m_streamIn = 0;<br />
    return true;<br />
}//stopPaRecorder()</p>
<p>bool AudioEngine::stopPaPlayback()<br />
{<br />
    if (m_streamOut)<br />
        Pa_CloseStream(m_streamOut);<br />
    m_streamOut = 0;<br />
    return true;<br />
}//stopPaPlayback()</p>
<p>bool AudioEngine::stopPaRecorderPlaybackLoop()<br />
{<br />
    return stopPaRecorder();<br />
}//stopPaRecorderPlaybackLoop()</p>
<p>void AudioEngine::sendRecordDataOut(char *buf, int len)<br />
{<br />
    if (m_isSelfLoop)<br />
        return;</p>
<p>    if (!m_recorderId.isNull() &#38;&#38; m_serverSocket)<br />
    {<br />
        QByteArray ba;<br />
        ba.setRawData(buf, len);<br />
        m_serverSocket-&#62;send(ba, m_recorderId);<br />
        ba.resetRawData(buf, len);<br />
    }<br />
}//sendRecordDataOut()</p>
<p>void AudioEngine::recvPlaybackDataIn(const QByteArray&#38; ba)<br />
{<br />
    if (m_isSelfLoop)<br />
        return;</p>
<p>    //buffer:<br />
    //  encodedBufSize + 4 &#124; timestamp &#124; encodedBuf<br />
    // &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
    //  4                  &#124;  4        &#124; encodedBufSize &#8211; 4<br />
    int len = 0;<br />
    if (!m_playbackId.isNull() &#38;&#38; (len = ba.size()) &#62; <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /><br />
    {<br />
        char *buf = new char [len];<br />
        memcpy(buf, ba.data(), len);<br />
        m_data.speexdec.put(buf+4, len-4); //encodedBufWithTimeStamp<br />
        delete [] buf;<br />
        buf = 0;<br />
    }<br />
}//recvPlaybackDataIn()</p>
<p>void AudioEngine::setSelfLoop(bool flag)<br />
{<br />
    m_isSelfLoop = flag;<br />
    if (m_isSelfLoop)<br />
    {<br />
        m_recorderId = &#8220;recorder&#8221;;<br />
        m_playbackId = &#8220;playback&#8221;;<br />
    }<br />
}</p>
<p>&#160;</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Testing portaudio and speex - part 3]]></title>
<link>http://slworkthings.wordpress.com/2009/11/11/testing-portaudio-and-speex-part-3/</link>
<pubDate>Wed, 11 Nov 2009 00:34:31 +0000</pubDate>
<dc:creator>slworkthings</dc:creator>
<guid>http://slworkthings.wordpress.com/2009/11/11/testing-portaudio-and-speex-part-3/</guid>
<description><![CDATA[Continue. speex header file: #ifndef _SAN_SPEEX_H_ #define _SAN_SPEEX_H_ //copy from speex_jitter_bu]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Continue.</p>
<p>speex header file:</p>
<p>#ifndef _SAN_SPEEX_H_<br />
#define _SAN_SPEEX_H_<br />
//copy from speex_jitter_buffer.h(.c)<br />
#include &#60;speex/speex_jitter.h&#62;<br />
#include &#60;speex/speex.h&#62;<br />
#include &#60;speex/speex.h&#62;<br />
#include &#60;speex/speex_jitter.h&#62;<br />
#include &#60;speex/speex_preprocess.h&#62;<br />
#include &#60;speex/speex_echo.h&#62;<br />
#ifdef __cplusplus<br />
extern &#8220;C&#8221; {<br />
#endif</p>
<p>/** @defgroup SpeexJitter SpeexJitter: Adaptive jitter buffer specifically for Speex<br />
 *  This is the jitter buffer that reorders UDP/RTP packets and adjusts the buffer size<br />
 * to maintain good quality and low latency. This is a simplified version that works only<br />
 * with Speex, but is much easier to use.<br />
 *  @{<br />
*/</p>
<p>/** Speex jitter-buffer state. Never use it directly! */<br />
typedef struct SpeexJitter {<br />
   SpeexBits current_packet;         /**&#60; Current Speex packet */<br />
   int valid_bits;                   /**&#60; True if Speex bits are valid */<br />
   JitterBuffer *packets;            /**&#60; Generic jitter buffer state */<br />
   void *dec;                        /**&#60; Pointer to Speex decoder */<br />
   spx_int32_t frame_size;           /**&#60; Frame size of Speex decoder */<br />
} SpeexJitter;</p>
<p>/** Initialise jitter buffer<br />
 *<br />
 * @param jitter State of the Speex jitter buffer<br />
 * @param decoder Speex decoder to call<br />
 * @param sampling_rate Sampling rate used by the decoder<br />
*/<br />
void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate);</p>
<p>/** Destroy jitter buffer */<br />
void speex_jitter_destroy(SpeexJitter *jitter);</p>
<p>/** Put one packet into the jitter buffer */<br />
void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp);</p>
<p>/** Get one packet from the jitter buffer */<br />
void speex_jitter_get(SpeexJitter *jitter, spx_int16_t *out, int *start_offset);</p>
<p>/** Get pointer timestamp of jitter buffer */<br />
int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter);</p>
<p>#ifdef __cplusplus<br />
}<br />
#endif<br />
#define SAMPLING_RATE 16000<br />
#define FRAME_SIZE 320<br />
////////////////////////////////////////////////////////////////////</p>
<p>class SanSpeexEnc<br />
{<br />
public:<br />
    SanSpeexEnc();<br />
    ~SanSpeexEnc();</p>
<p>    /**<br />
     * @return 4 + 4 + encodedLen<br />
     * @rawin  must be 320 length<br />
     *  4+encodedLen &#124;   timestamp  &#124; encodedBuf<br />
     * &#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8211;<br />
     *  4            &#124;   4          &#124; encodedLen<br />
     */<br />
    int encode(const short *rawin, char *encodedBufOutWithTimestampAndLen);</p>
<p>    int playbackEcho(const short *rawin, bool ok); //TODO: remember to sync</p>
<p>    void captureEcho(short *rawin);<br />
    void captureEcho(short *rawin, short *playback);</p>
<p>private:<br />
    SpeexPreprocessState *preprocess;<br />
    void                 *enc_state;<br />
    SpeexBits             enc_bits;<br />
    int                   send_timestamp;<br />
    short                 pcm[FRAME_SIZE], pcm2[FRAME_SIZE];<br />
    SpeexEchoState       *echo_state;<br />
    char                  encodedBuf[FRAME_SIZE*2];</p>
<p>};<br />
class SanSpeexDec<br />
{<br />
public:<br />
    SanSpeexDec();<br />
    ~SanSpeexDec();</p>
<p>    void setSanSpeexEnc(SanSpeexEnc *ptr);<br />
    int put(const char *encodedBufWithTimestamp, int encodedLenWithTimestamp);<br />
    int get(short *rawout);<br />
    int afterPlayback(short *rawin, bool ok);</p>
<p>private:<br />
   void               *dec_state;<br />
   SpeexBits           dec_bits;<br />
   short               pcm[FRAME_SIZE];<br />
   SanSpeexEnc        *speexenc;<br />
   SpeexJitter         jitter;<br />
   int                 mostUpdatedTSatPut;<br />
   bool                firsttimecalling_get;</p>
<p>};</p>
<p>/////////////////////////////////////////////////////////////////////</p>
<p>&#160;</p>
<p>#endif // _SAN_SPEEX_H_</p>
<p>Speex source file:<br />
#include &#60;stdio.h&#62;<br />
#include &#60;limits.h&#62;<br />
#include &#8220;san_speex.h&#8221;<br />
#ifndef NULL<br />
#define NULL 0<br />
#endif<br />
#define ENABLE_AEC<br />
#ifdef ENABLE_AEC<br />
 #define USE_AEC_CAPTURE          /* will print a lot of speex warning */<br />
#endif</p>
<p>#include &#60;qglobal.h&#62;<br />
//#define NEED_DUMP<br />
#include &#60;stdio.h&#62;<br />
FILE *file = 0;<br />
char msg[128];<br />
void debugPrint(const char *msg)<br />
{<br />
#ifdef NEED_DUMP<br />
    if (file == 0)<br />
        file = fopen(&#8220;dump.txt&#8221;, &#8220;a&#8221;);<br />
    fprintf(file, msg);<br />
#endif<br />
}</p>
<p>void closeDebugPrint()<br />
{<br />
#ifdef NEED_DUMP<br />
    if (file)<br />
        fclose(file);<br />
    file = 0;<br />
#endif<br />
}</p>
<p>#define ECHOTAILSIZE  25<br />
short psSpeaker[320 * ECHOTAILSIZE * 10];<br />
void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate)<br />
{<br />
   jitter-&#62;dec = decoder;<br />
   speex_decoder_ctl(decoder, SPEEX_GET_FRAME_SIZE, &#38;jitter-&#62;frame_size);</p>
<p>   jitter-&#62;packets = jitter_buffer_init(jitter-&#62;frame_size);</p>
<p>   speex_bits_init(&#38;jitter-&#62;current_packet);<br />
   jitter-&#62;valid_bits = 0;<br />
}</p>
<p>void speex_jitter_destroy(SpeexJitter *jitter)<br />
{<br />
   jitter_buffer_destroy(jitter-&#62;packets);<br />
   speex_bits_destroy(&#38;jitter-&#62;current_packet);<br />
}</p>
<p>void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp)<br />
{<br />
   JitterBufferPacket p;<br />
   p.data = packet;<br />
   p.len = len;<br />
   p.timestamp = timestamp;<br />
   p.span = jitter-&#62;frame_size;<br />
   jitter_buffer_put(jitter-&#62;packets, &#38;p);<br />
   sprintf(msg, &#8220;put %d\n&#8221;, timestamp);<br />
   debugPrint(msg);<br />
}</p>
<p>void speex_jitter_get(SpeexJitter *jitter, spx_int16_t *out, int *current_timestamp)<br />
{<br />
   int i;<br />
   int ret;<br />
   spx_int32_t activity;<br />
   int bufferCount = 0;<br />
   JitterBufferPacket packet;<br />
   //char data[40960];<br />
   //packet.data = data;<br />
   //packet.len = 40960;<br />
   packet.data = reinterpret_cast&#60;char *&#62;(psSpeaker);<br />
   packet.len = 320 * ECHOTAILSIZE * 10;<br />
  <br />
   if (jitter-&#62;valid_bits)<br />
   {<br />
      /* Try decoding last received packet */<br />
      ret = speex_decode_int(jitter-&#62;dec, &#38;jitter-&#62;current_packet, out);<br />
      if (ret == 0)<br />
      {<br />
         jitter_buffer_tick(jitter-&#62;packets);<br />
         return;<br />
      } else {<br />
         jitter-&#62;valid_bits = 0;<br />
      }<br />
   }</p>
<p>   if (current_timestamp)<br />
    ret = jitter_buffer_get(jitter-&#62;packets, &#38;packet, jitter-&#62;frame_size, current_timestamp);<br />
   else<br />
    ret = jitter_buffer_get(jitter-&#62;packets, &#38;packet, jitter-&#62;frame_size, NULL);<br />
  <br />
   if (ret != JITTER_BUFFER_OK)<br />
   {<br />
      /* No packet found */<br />
      speex_decode_int(jitter-&#62;dec, NULL, out);<br />
   } else {<br />
      speex_bits_read_from(&#38;jitter-&#62;current_packet, packet.data, packet.len);<br />
      /* Decode packet */<br />
      ret = speex_decode_int(jitter-&#62;dec, &#38;jitter-&#62;current_packet, out);<br />
      if (ret == 0)<br />
      {<br />
         jitter-&#62;valid_bits = 1;<br />
      } else {<br />
         /* Error while decoding */<br />
         for (i=0;i&#60;jitter-&#62;frame_size;i++)<br />
            out[i]=0;<br />
      }<br />
   }<br />
   speex_decoder_ctl(jitter-&#62;dec, SPEEX_GET_ACTIVITY, &#38;activity);<br />
   if (activity &#60; 30)<br />
   {<br />
      jitter_buffer_update_delay(jitter-&#62;packets, &#38;packet, NULL);<br />
   }<br />
   jitter_buffer_tick(jitter-&#62;packets);<br />
   //ret = jitter_buffer_ctl(jitter-&#62;packets, JITTER_BUFFER_GET_AVALIABLE_COUNT, &#38;bufferCount);<br />
   //sprintf(msg, &#8220;   get %d bufferCount=%d\n&#8221;, speex_jitter_get_pointer_timestamp(jitter), bufferCount);<br />
   //debugPrint(msg);<br />
}</p>
<p>int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter)<br />
{<br />
   return jitter_buffer_get_pointer_timestamp(jitter-&#62;packets);<br />
}<br />
//===========================================================<br />
SanSpeexEnc::SanSpeexEnc()<br />
            :preprocess(0),<br />
             enc_state(0),<br />
             enc_bits(),<br />
             send_timestamp(0),<br />
             echo_state(0)<br />
{<br />
    for (int i=0; i&#60;FRAME_SIZE; i++)<br />
        pcm[i] = 0;</p>
<p>    int tmp;<br />
    float tmpf;</p>
<p>    enc_state = speex_encoder_init(&#38;speex_wb_mode);<br />
    tmp = 3; //3,4,7,8,9,10 are not working<br />
    speex_encoder_ctl(enc_state, SPEEX_SET_QUALITY, &#38;tmp);<br />
    tmp = 7;<br />
    speex_encoder_ctl(enc_state, SPEEX_SET_COMPLEXITY, &#38;tmp);<br />
    speex_bits_init(&#38;enc_bits);</p>
<p>    echo_state = speex_echo_state_init(FRAME_SIZE, ECHOTAILSIZE*FRAME_SIZE);<br />
    tmp = SAMPLING_RATE;<br />
    speex_echo_ctl(echo_state, SPEEX_ECHO_SET_SAMPLING_RATE, &#38;tmp);</p>
<p>    preprocess = speex_preprocess_state_init(FRAME_SIZE, SAMPLING_RATE);<br />
    speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_ECHO_STATE, echo_state);</p>
<p>    tmp = 1;<br />
    speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_DENOISE, &#38;tmp);<br />
    tmp = 0;<br />
    speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_AGC, &#38;tmp);<br />
    tmp = 1;<br />
    speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_VAD, &#38;tmp);</p>
<p>    tmp = 0;<br />
 speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_DEREVERB, &#38;tmp);<br />
    tmpf = 0.0;<br />
    speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &#38;tmpf);<br />
    tmpf = 0.0;<br />
    speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &#38;tmpf);</p>
<p>    tmp = 8000;//30000;<br />
    //speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_AGC_TARGET, &#38;tmp);<br />
    tmp = 8000;<br />
    speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_AGC_LEVEL, &#38;tmp);<br />
    tmp = 5;<br />
    //speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_AGC_MAX_GAIN, &#38;tmp);<br />
    tmp = -30;<br />
    speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &#38;tmp);<br />
}</p>
<p>SanSpeexEnc::~SanSpeexEnc()<br />
{<br />
    speex_encoder_destroy(enc_state); //&#8211;Destroy the encoder state<br />
    speex_echo_state_destroy(echo_state);<br />
    speex_preprocess_state_destroy(preprocess);<br />
    speex_bits_destroy(&#38;enc_bits); //&#8211;Destroy the bit-packing struct<br />
    closeDebugPrint();<br />
}</p>
<p>/**<br />
 * @return 4 + 4 + encodedLen<br />
 * @rawin  must be 320 length<br />
 *  4+encodedLen &#124;   timestamp  &#124; encodedBuf<br />
 * &#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8211;<br />
 *  4            &#124;   4          &#124; encodedLen<br />
 */<br />
int SanSpeexEnc::encode(const short *rawin, char *encodedBufOutWithTimestampAndLen)<br />
{<br />
#ifdef ENABLE_AEC<br />
    /* Perform echo cancellation */<br />
   #ifdef USE_AEC_CAPTURE<br />
    speex_echo_capture(echo_state, rawin, pcm2);<br />
   #else<br />
    speex_echo_cancellation(echo_state, rawin, psSpeaker, pcm2);<br />
   #endif<br />
    for (int i=0;i&#60;FRAME_SIZE;i++)<br />
        pcm[i] = pcm2[i];<br />
#else<br />
    for (int i=0;i&#60;FRAME_SIZE;i++)<br />
        pcm[i] = rawin[i];<br />
#endif</p>
<p>    speex_bits_reset(&#38;enc_bits);</p>
<p>    /* Apply noise/echo suppression */<br />
    bool isSpeech = speex_preprocess_run(preprocess, pcm);<br />
    /* Encode */<br />
    int needTransmit = speex_encode_int(enc_state, pcm, &#38;enc_bits);<br />
    int packetSize = 0;<br />
    if (isSpeech &#38;&#38; needTransmit)<br />
    {<br />
        packetSize = speex_bits_write(&#38;enc_bits, encodedBufOutWithTimestampAndLen+8, FRAME_SIZE*2);<br />
        <br />
        ((int*)encodedBufOutWithTimestampAndLen)[0] = packetSize+4;<br />
        ((int*)encodedBufOutWithTimestampAndLen)[1] = send_timestamp;<br />
        qDebug(&#8220;packetSize=%d, timestamp=%d&#8221;, packetSize, send_timestamp);<br />
    }</p>
<p>    send_timestamp += FRAME_SIZE;</p>
<p>    if (send_timestamp &#62;= INT_MAX)<br />
        send_timestamp = 0;</p>
<p>    if (packetSize &#62; 0)<br />
        return packetSize+4+4;<br />
    else<br />
        return 0;<br />
}</p>
<p>int SanSpeexEnc::playbackEcho(const short *rawin, bool ok)<br />
{<br />
#ifdef ENABLE_AEC<br />
    //TODO : sync<br />
    /* Put frame into playback buffer */<br />
   #ifdef USE_AEC_CAPTURE<br />
    if (!ok)<br />
        speex_echo_state_reset(echo_state);<br />
    speex_echo_playback(echo_state, rawin);<br />
   #endif<br />
#endif<br />
    return 1;<br />
}</p>
<p>void SanSpeexEnc::captureEcho(short *rawin)<br />
{<br />
#ifdef ENABLE_AEC<br />
   #ifdef USE_AEC_CAPTURE<br />
    speex_echo_capture(echo_state, rawin, pcm2);<br />
    for (int i=0; i&#60;FRAME_SIZE; i++)<br />
        rawin[i] = pcm2[i];</p>
<p>    speex_bits_reset(&#38;enc_bits);<br />
    speex_preprocess_run(preprocess, rawin);<br />
   #endif<br />
#endif<br />
}</p>
<p>void SanSpeexEnc::captureEcho(short *rawin, short *playback)<br />
{<br />
#ifdef ENABLE_AEC<br />
    speex_echo_cancellation(echo_state, rawin, playback, pcm2);<br />
    speex_preprocess_run(preprocess, pcm2);<br />
    for (int i=0; i&#60;FRAME_SIZE; i++)<br />
        rawin[i] = pcm2[i];<br />
#endif<br />
}</p>
<p>//==================================================<br />
SanSpeexDec::SanSpeexDec()<br />
            :dec_state(0),<br />
             dec_bits(),<br />
             speexenc(0),<br />
             jitter(),<br />
             mostUpdatedTSatPut(0),<br />
             firsttimecalling_get(true)<br />
{<br />
    for (int i=0; i&#60;FRAME_SIZE; i++)<br />
        pcm[i] = 0;<br />
    int tmp;</p>
<p>    dec_state = speex_decoder_init(&#38;speex_wb_mode);<br />
    tmp = 1;<br />
    speex_decoder_ctl(dec_state, SPEEX_SET_ENH, &#38;tmp);<br />
    speex_bits_init(&#38;dec_bits);<br />
    speex_jitter_init(&#38;jitter, dec_state, SAMPLING_RATE);<br />
}</p>
<p>SanSpeexDec::~SanSpeexDec()<br />
{<br />
    speex_jitter_destroy(&#38;jitter);</p>
<p>    //&#8211;Destroy the decoder state<br />
    speex_decoder_destroy(dec_state);</p>
<p>    //&#8211;Destroy the bit-stream truct<br />
    speex_bits_destroy(&#38;dec_bits);<br />
}</p>
<p>void SanSpeexDec::setSanSpeexEnc(SanSpeexEnc *ptr)<br />
{<br />
    speexenc = ptr;<br />
}</p>
<p>int SanSpeexDec::put(const char *encodedBufWithTimestamp, int encodedLenWithTimestamp)<br />
{<br />
    //buffer:<br />
    //  timestamp &#124; encodedBuf<br />
    // &#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
    //   4        &#124; encodedLenWithTimestamp &#8211; 4<br />
    int success = 0;<br />
    int recv_timestamp = ((int*)encodedBufWithTimestamp)[0];<br />
    mostUpdatedTSatPut = recv_timestamp;<br />
    if (firsttimecalling_get)<br />
        return 1;<br />
    speex_jitter_put(&#38;jitter, (char *)encodedBufWithTimestamp+4, encodedLenWithTimestamp-4, recv_timestamp);<br />
    return 1;<br />
}</p>
<p>int SanSpeexDec::get(short *rawout)<br />
{<br />
    if (firsttimecalling_get)<br />
    {<br />
        int ts = mostUpdatedTSatPut;<br />
        sprintf(msg, &#8220;MostUpdatedTSatPut = %d\n&#8221;, ts);<br />
        debugPrint(msg);<br />
        firsttimecalling_get = false;<br />
        speex_jitter_get(&#38;jitter, rawout, &#38;ts);<br />
    }<br />
    else<br />
        speex_jitter_get(&#38;jitter, rawout, 0);<br />
    return 1;<br />
}</p>
<p>int SanSpeexDec::afterPlayback(short *rawin, bool ok)<br />
{<br />
    if (speexenc)<br />
        return speexenc-&#62;playbackEcho(rawin, ok);<br />
    return 0;<br />
}</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Testing portaudio and speex - part 2]]></title>
<link>http://slworkthings.wordpress.com/2009/11/11/testing-portaudio-and-speex-part-2/</link>
<pubDate>Wed, 11 Nov 2009 00:32:56 +0000</pubDate>
<dc:creator>slworkthings</dc:creator>
<guid>http://slworkthings.wordpress.com/2009/11/11/testing-portaudio-and-speex-part-2/</guid>
<description><![CDATA[Continue. AudioClient header file: #include &#8220;mysocket.h&#8221; //=============================]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Continue.</p>
<p>AudioClient header file:<br />
#include &#8220;mysocket.h&#8221;</p>
<p>//==============================================================<br />
MySocket::MySocket(const QString&#38; myId)<br />
         :m_socketdevice(0),<br />
          m_running(false),<br />
          m_amIClient(true),<br />
          m_buf(0),<br />
          m_bufLen(1024),<br />
          m_myId(myId)<br />
{<br />
    m_socketdevice = new QSocketDevice();<br />
    m_socketdevice-&#62;setAddressReusable(true);<br />
    m_socketdevice-&#62;setBlocking(true);</p>
<p>    m_buf = new char[m_bufLen];<br />
}</p>
<p>MySocket::~MySocket()<br />
{<br />
    stop();</p>
<p>    delete m_socketdevice;<br />
    m_socketdevice = 0;</p>
<p>    delete [] m_buf;<br />
    m_buf = 0;<br />
}</p>
<p>void MySocket::setId(const QString&#38; id)<br />
{<br />
    m_myId = id;<br />
}</p>
<p>void MySocket::stop()<br />
{<br />
    if (m_running)<br />
    {<br />
        m_running = false;<br />
    }<br />
    if (m_socketdevice)<br />
        m_socketdevice-&#62;close();<br />
    //wait(500);<br />
    qDebug(&#8220;MySocket::stop&#8221;);<br />
}</p>
<p>bool MySocket::connectTo(const QString&#38; serverAddr, int port)<br />
{<br />
    m_amIClient = true;<br />
    if (!m_socketdevice)<br />
        return false;</p>
<p>    bool ok = m_socketdevice-&#62;connect(serverAddr, port);<br />
    wait(1000);<br />
    if (ok)<br />
    {<br />
        QString handshake = &#8220;myid=&#8221; + m_myId;<br />
        send(handshake);<br />
    }<br />
    return ok;<br />
}</p>
<p>void MySocket::setSocket(int socket)<br />
{<br />
    m_amIClient = false;<br />
    m_socketdevice-&#62;setSocket(socket, QSocketDevice::Stream);<br />
}</p>
<p>bool MySocket::hasError()<br />
{<br />
    if (!m_socketdevice)<br />
        return true;<br />
    return (m_socketdevice-&#62;error() != QSocketDevice::NoError);<br />
}</p>
<p>void MySocket::run()<br />
{<br />
    m_running = true;</p>
<p>    if (m_socketdevice)<br />
    {<br />
        qDebug(&#8220;port/peerPort = %d,%d&#8221;, m_socketdevice-&#62;port(), m_socketdevice-&#62;peerPort());<br />
    }</p>
<p>    int len = 0;<br />
    int readLen = 0;<br />
    while (m_running &#38;&#38; m_socketdevice &#38;&#38; !hasError())<br />
    {<br />
        len = m_socketdevice-&#62;bytesAvailable();<br />
        if (len &#62; 0)<br />
        {<br />
            if (len &#62; m_bufLen)<br />
            {<br />
                m_bufLen = len;<br />
                delete [] m_buf;<br />
                m_buf = new char[m_bufLen];<br />
            }</p>
<p>            readLen = m_socketdevice-&#62;readBlock(m_buf, len);<br />
            if (readLen &#60;= 0) //error<br />
            {<br />
                qDebug(&#8220;&#8212;&#8211; read error &#8212; 1&#8243;);<br />
                m_running = false;<br />
                break;<br />
            }<br />
            while (readLen &#60; len &#38;&#38; !hasError())<br />
            {<br />
                int curLen = m_socketdevice-&#62;readBlock(m_buf + readLen, len &#8211; readLen);<br />
                if (curLen &#60;= 0) //error<br />
                {<br />
                    qDebug(&#8220;&#8212;&#8211; read error &#8212; 3&#8243;);<br />
                    m_running = false;<br />
                    break;<br />
                }<br />
                readLen += curLen;<br />
            }<br />
            if (!m_running)<br />
                break;</p>
<p>            QByteArray ba(len);<br />
            const char *data = ba.data();<br />
            memcpy(ba.data(), m_buf, len);<br />
            if (len &#62; 5 &#38;&#38; data[0] == &#8216;m&#8217; &#38;&#38; data[1] == &#8216;y&#8217; &#38;&#38; data[2] == &#8216;i&#8217; &#38;&#38; data[3] == &#8216;d&#8217; &#38;&#38; data[4] == &#8216;=&#8217;)<br />
            {<br />
                QString handshake(ba);<br />
                QString hisId = handshake.mid(5);<br />
                emit fireReceivedHandshake(m_socketdevice-&#62;socket(), hisId);<br />
            }<br />
            else if (len &#62; 3 &#38;&#38; data[0] == &#8216;c&#8217; &#38;&#38; data[1] == &#8216;m&#8217; &#38;&#38; data[2] == &#8216;d&#8217; &#38;&#38; data[3] == &#8216;Q&#8217;)<br />
            {<br />
                m_running = false;<br />
                qDebug(&#8220;MySocket::run() got cmdQ&#8221;);<br />
                emit fireReceivedData(ba);<br />
            }<br />
            else<br />
                emit fireReceivedData(ba);<br />
        }<br />
        else<br />
        {<br />
            len = m_socketdevice-&#62;waitForMore(100);<br />
            if (len == -1 &#124;&#124; hasError()) //error<br />
            {<br />
                qDebug(&#8220;&#8212;&#8211; read error &#8212; 2&#8243;);<br />
                m_running = false;<br />
                break;<br />
            }<br />
        }<br />
    }//while()<br />
    qDebug(&#8220;&#8212;&#8211; done MySocket::run() &#8212;-&#8221;);<br />
}//run()</p>
<p>bool MySocket::send(const QByteArray&#38; ba)<br />
{<br />
    bool success = false;<br />
    if (!m_socketdevice)<br />
        return success;</p>
<p>    const char *data = ba.data();<br />
    int len = ba.size();<br />
    int writtenLen = 0;</p>
<p>   <br />
    writtenLen = m_socketdevice-&#62;writeBlock(data, len);<br />
    while (writtenLen &#60; len)<br />
    {<br />
        writtenLen += m_socketdevice-&#62;writeBlock(data + writtenLen, len &#8211; writtenLen);<br />
    }</p>
<p>    return (writtenLen == len);<br />
}</p>
<p>bool MySocket::send(const QString&#38; str)<br />
{<br />
    QCString cstr = str.utf8();<br />
    const char *data = (const char *)(cstr);<br />
    QByteArray ba(cstr.length());<br />
    memcpy(ba.data(), data, cstr.length());</p>
<p>    return send(ba);<br />
}<br />
//=====================================================<br />
MyServerSocket::MyServerSocket(Q_UINT16 port)<br />
               :QServerSocket(port),<br />
                m_mysocketDict(), //key=socket(int)<br />
                m_map() //socket(int), id(Qstring)<br />
{<br />
    m_mysocketDict.setAutoDelete(true);<br />
}</p>
<p>MyServerSocket::~MyServerSocket()<br />
{<br />
    m_mysocketDict.clear();<br />
    m_map.clear();<br />
}</p>
<p>void MyServerSocket::newConnection(int socket)<br />
{<br />
    MySocket *mysocket = new MySocket();<br />
    connect(mysocket, SIGNAL(fireReceivedData(const QByteArray&#38;)),<br />
                      SIGNAL(fireReceivedData(const QByteArray&#38;)));<br />
    connect(mysocket, SIGNAL(fireReceivedHandshake(int, const QString&#38;)),<br />
                      SLOT(slotReceivedHandshake(int, const QString&#38;)));<br />
    m_map.insert(socket, QString(&#8220;&#8221;));<br />
    m_mysocketDict.insert(QString::number(socket), mysocket);<br />
    mysocket-&#62;setSocket(socket);<br />
    mysocket-&#62;start();<br />
}</p>
<p>bool MyServerSocket::send(const QByteArray&#38; ba, const QString&#38; _id)<br />
{<br />
    QMap&#60;int, QString&#62;::Iterator it;<br />
    for (it = m_map.begin(); it != m_map.end(); ++it)<br />
    {<br />
        int key = it.key();<br />
        QString id = it.data();<br />
        if (id == _id) //found it<br />
        {<br />
            MySocket *sock = m_mysocketDict.find(QString::number(key));<br />
            if (sock)<br />
            {<br />
                return sock-&#62;send(ba);<br />
            }<br />
        }<br />
    }<br />
    return false;<br />
}</p>
<p>bool MyServerSocket::send(const QString&#38; str, const QString&#38; _id)<br />
{<br />
    QMap&#60;int, QString&#62;::Iterator it;<br />
    for (it = m_map.begin(); it != m_map.end(); ++it)<br />
    {<br />
        int key = it.key();<br />
        QString id = it.data();<br />
        if (id == _id) //found it<br />
        {<br />
            MySocket *sock = m_mysocketDict.find(QString::number(key));<br />
            if (sock)<br />
            {<br />
                return sock-&#62;send(str);<br />
            }<br />
        }<br />
    }<br />
    return false;<br />
}</p>
<p>void MyServerSocket::stop()<br />
{<br />
    QDictIterator&#60;MySocket&#62; it(m_mysocketDict);<br />
    MySocket *sock = 0;<br />
    for ( ; (sock = it.current()); ++it)<br />
    {<br />
        sock-&#62;stop();<br />
    }<br />
}</p>
<p>void MyServerSocket::slotReceivedHandshake(int socket, const QString&#38; hisId)<br />
{<br />
    qDebug(&#8220;&#8212;- receive handshake :&#8221; + QString::number(socket) + &#8221; =&#8221; + hisId);<br />
    m_map.insert(socket, hisId, true);<br />
    MySocket *sock = m_mysocketDict.find(QString::number(socket));<br />
    if (sock)<br />
    {<br />
        sock-&#62;setId(hisId);<br />
        emit fireReceivedHandshake(hisId);<br />
    }<br />
}</p>
<p> AudioClient source file:</p>
<p>#include &#8220;audioclient.h&#8221;<br />
#include &#60;qpushbutton.h&#62;<br />
#include &#60;qlabel.h&#62;<br />
#include &#60;qlayout.h&#62;<br />
#include &#60;qlineedit.h&#62;<br />
#include &#60;qapplication.h&#62;</p>
<p>//===================================<br />
AudioClient::AudioClient(int serverPort, bool isRecorder)<br />
            :QWidget(),<br />
             m_socket(0),<br />
             m_setBtn(0),<br />
             m_startBtn(0),<br />
             m_stopBtn(0),<br />
             m_edit(0),<br />
             m_isRecorder(isRecorder)<br />
{<br />
    m_socket = new MySocket(isRecorder ? &#8220;recorder&#8221; : &#8220;playback&#8221;);<br />
    connect(m_socket, SIGNAL(fireReceivedData(const QByteArray&#38;)),<br />
                      SLOT(slotReceivedData(const QByteArray&#38;)));</p>
<p>    QVBoxLayout *vlayout = new QVBoxLayout(this);</p>
<p>    QHBoxLayout *h1 = new QHBoxLayout(0);<br />
    QLabel *label1 = new QLabel(&#8220;Set Device Index:&#8221;, this);<br />
    m_edit = new QLineEdit(this);<br />
    m_edit-&#62;setText(isRecorder ? &#8220;1&#8243; : &#8220;7&#8243;);<br />
    m_setBtn = new QPushButton(isRecorder ? &#8220;Set Capture Dev&#8221; : &#8220;Set Playback Dev&#8221;, this);<br />
    h1-&#62;addWidget(label1);<br />
    h1-&#62;addWidget(m_edit);<br />
    h1-&#62;addWidget(m_setBtn);<br />
    vlayout-&#62;addItem(h1);</p>
<p>    QHBoxLayout *h2 = new QHBoxLayout(0);<br />
    QLabel *label2 = new QLabel(isRecorder ? &#8220;Start Capture&#8221; : &#8220;Start Playback&#8221;, this);<br />
    m_startBtn = new QPushButton(&#8220;Start&#8221;, this);<br />
    h2-&#62;addWidget(label2);<br />
    h2-&#62;addWidget(m_startBtn);<br />
    vlayout-&#62;addItem(h2);</p>
<p>    QHBoxLayout *h3 = new QHBoxLayout(0);<br />
    QLabel *label3 = new QLabel(isRecorder ? &#8220;Stop Capture&#8221; : &#8220;Stop Playback&#8221;, this);<br />
    m_stopBtn = new QPushButton(&#8220;Stop&#8221;, this);<br />
    h3-&#62;addWidget(label3);<br />
    h3-&#62;addWidget(m_stopBtn);<br />
    vlayout-&#62;addItem(h3);</p>
<p>    QPushButton *exitBtn = new QPushButton(&#8220;Exit&#8221;, this);<br />
    vlayout-&#62;addWidget(exitBtn);</p>
<p>    connect(m_setBtn,   SIGNAL(clicked()), SLOT(slotSetClicked()));<br />
    connect(m_startBtn, SIGNAL(clicked()), SLOT(slotStartClicked()));<br />
    connect(m_stopBtn,  SIGNAL(clicked()), SLOT(slotStopClicked()));<br />
    connect(exitBtn,    SIGNAL(clicked()), SLOT(slotExitClicked()));</p>
<p>    move(isRecorder ? 30 : 130, isRecorder ? 30 : 130);<br />
    setCaption(isRecorder ? &#8220;RecorderClient&#8221; : &#8220;PlaybackClient&#8221;);</p>
<p>    bool ok = m_socket-&#62;connectTo(&#8220;127.0.0.1&#8243;, serverPort);<br />
    qDebug(&#8220;connect to = %d&#8221;, ok);<br />
    if (ok)<br />
        m_socket-&#62;start();<br />
}</p>
<p>AudioClient::~AudioClient()<br />
{<br />
    delete m_socket;<br />
    m_socket = 0;<br />
}</p>
<p>void AudioClient::slotSetClicked()<br />
{<br />
    QString str = m_isRecorder ? &#8220;cmd2&#8243; : &#8220;cmd3&#8243;;<br />
    str += m_edit-&#62;text().stripWhiteSpace();<br />
    m_socket-&#62;send(str);<br />
    m_setBtn-&#62;setEnabled(false);<br />
}</p>
<p>void AudioClient::slotStartClicked()<br />
{<br />
    m_socket-&#62;send(m_isRecorder ? &#8220;cmd4&#8243; : &#8220;cmd5&#8243;);<br />
    m_startBtn-&#62;setEnabled(false);<br />
}</p>
<p>void AudioClient::slotStopClicked()<br />
{<br />
    m_socket-&#62;send(m_isRecorder ? &#8220;cmd6&#8243; : &#8220;cmd7&#8243;);<br />
    m_stopBtn-&#62;setEnabled(false);<br />
}</p>
<p>void AudioClient::slotExitClicked()<br />
{<br />
    if (m_socket &#38;&#38; m_socket-&#62;isValid())<br />
    {<br />
        m_socket-&#62;send(&#8220;cmdQ&#8221;);<br />
        m_socket-&#62;stop();<br />
    }<br />
    close();<br />
    qApp-&#62;quit();<br />
}</p>
<p>void AudioClient::closeEvent(QCloseEvent *)<br />
{<br />
    if (m_socket &#38;&#38; m_socket-&#62;isValid())<br />
    {<br />
        m_socket-&#62;send(&#8220;cmdQ&#8221;);<br />
        m_socket-&#62;stop();<br />
    }<br />
    qApp-&#62;quit();<br />
}</p>
<p>void AudioClient::slotReceivedData(const QByteArray&#38; ba)<br />
{<br />
    const char *data = ba.data();<br />
    if (ba.size() &#62;= 4 &#38;&#38; data[0] == &#8216;c&#8217; &#38;&#38; data[1] == &#8216;m&#8217; &#38;&#38; data[2] == &#8216;d&#8217;)<br />
    {<br />
        char cmd = data[3];<br />
        switch (cmd)<br />
        {<br />
        case &#8216;1&#8242;: //return device list;   dev1\ndev2\n&#8230;<br />
            {<br />
                QString devList(ba);<br />
                devList = devList.mid(4);<br />
                qDebug(&#8220;1. DevList = &#8221; + devList);<br />
            }<br />
            break;<br />
        case &#8216;2&#8242;: //set recorder device;  devname<br />
            {<br />
                QString devName(ba);<br />
                devName = devName.mid(4);<br />
                qDebug(&#8220;2. RecorderDevice = &#8221; + devName);<br />
            }<br />
            break;<br />
        case &#8216;3&#8242;: //set playback device; devname<br />
            {<br />
                QString devName(ba);<br />
                devName = devName.mid(4);<br />
                qDebug(&#8220;3. PlaybackDevice = &#8221; + devName);<br />
            }<br />
            break;<br />
        case &#8216;4&#8242;: //start recorder<br />
            qDebug(&#8220;4. Start Recording&#8221;);<br />
            break;<br />
        case &#8216;5&#8242;: //start playback<br />
            qDebug(&#8220;5. Start Playback&#8221;);<br />
            break;<br />
        case &#8216;6&#8242;: //stop recorder<br />
            qDebug(&#8220;6. Stop Recording&#8221;);<br />
            break;<br />
        case &#8216;7&#8242;: //stop playback<br />
            qDebug(&#8220;7. Stop Playback&#8221;);<br />
            break;<br />
        case &#8216;Q&#8217;:<br />
            qDebug(&#8220;Q. Quit&#8221;);<br />
            slotExitClicked();<br />
            break;<br />
        default:<br />
            break;<br />
        }<br />
    }//cmd<br />
    else<br />
    {<br />
        if (ba.size() &#62; <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /><br />
        {<br />
            const char *data = ba.data();<br />
            int packetSize = ((int*)data)[0];<br />
            int timestamp = ((int*)data)[1];<br />
            qDebug(&#8220;got packetSize=%d, timestamp=%d&#8221;, packetSize, timestamp);<br />
        }<br />
    }<br />
}//slotReceivedData()</p>
<p>&#160;</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Testing portaudio and speex - part 1]]></title>
<link>http://slworkthings.wordpress.com/2009/11/11/testing-portaudio-and-speex-part-1/</link>
<pubDate>Wed, 11 Nov 2009 00:31:08 +0000</pubDate>
<dc:creator>slworkthings</dc:creator>
<guid>http://slworkthings.wordpress.com/2009/11/11/testing-portaudio-and-speex-part-1/</guid>
<description><![CDATA[This is a testing program I wrote in QT3 to test audio capture/playback loop in a local machine. Usi]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>This is a testing program I wrote in QT3 to test audio capture/playback loop in a local machine. Using 2 testing clients to communicate with AudioEngine which handling audio capturing/playing. Of course, need a lot of improvement on audio quality and AGC, AEC&#8230; ,etc.</p>
<p>socket header file:<br />
#ifndef _MYSOCKET_H_<br />
#define _MYSOCKET_H_</p>
<p>#include &#60;qsocketdevice.h&#62;<br />
#include &#60;qthread.h&#62;<br />
#include &#60;qobject.h&#62;<br />
#include &#60;qserversocket.h&#62;<br />
#include &#60;qdict.h&#62;<br />
#include &#60;qmap.h&#62;</p>
<p>//==============================================<br />
class MySocket : public QObject, public QThread<br />
{<br />
    Q_OBJECT<br />
public:<br />
    MySocket(const QString&#38; myId = QString::null);<br />
    ~MySocket();</p>
<p>    //I am client<br />
    bool connectTo(const QString&#38; serverAddr, int port);</p>
<p>    //I am server<br />
    void setSocket(int socket);<br />
    void setId(const QString&#38; id);</p>
<p>    bool send(const QByteArray&#38;);<br />
    bool send(const QString&#38; str);<br />
    void stop();</p>
<p>    bool isValid() { return (m_socketdevice &#38;&#38; m_socketdevice-&#62;isValid()); }</p>
<p>signals:<br />
    void fireReceivedData(const QByteArray&#38;);<br />
    void fireReceivedHandshake(int socket, const QString&#38;);</p>
<p>protected:<br />
    virtual void run();</p>
<p>private:<br />
    bool             hasError();</p>
<p>    QSocketDevice   *m_socketdevice;<br />
    bool             m_running;<br />
    bool             m_amIClient;<br />
    char            *m_buf;<br />
    int              m_bufLen;<br />
    QString          m_myId;<br />
};<br />
//=====================================================<br />
class MyServerSocket : public QServerSocket<br />
{<br />
    Q_OBJECT<br />
public:<br />
    MyServerSocket(Q_UINT16 port = 4242);<br />
    ~MyServerSocket();</p>
<p>    bool send(const QByteArray&#38;, const QString&#38; id);<br />
    bool send(const QString&#38;, const QString&#38; id);<br />
    void stop();</p>
<p>signals:<br />
    void fireReceivedData(const QByteArray&#38;);<br />
    void fireReceivedHandshake(const QString&#38; hisId);</p>
<p>private slots:<br />
    void slotReceivedHandshake(int socket, const QString&#38; hisId);</p>
<p>protected:<br />
    virtual void newConnection(int socket);</p>
<p>private:<br />
    QDict&#60;MySocket&#62;      m_mysocketDict; //key=socket(int)<br />
    QMap&#60;int, QString&#62;   m_map;<br />
};<br />
#endif // _MYSOCKET_H_</p>
<p>socket source file:<br />
#include &#8220;mysocket.h&#8221;</p>
<p>//==============================================================<br />
MySocket::MySocket(const QString&#38; myId)<br />
         :m_socketdevice(0),<br />
          m_running(false),<br />
          m_amIClient(true),<br />
          m_buf(0),<br />
          m_bufLen(1024),<br />
          m_myId(myId)<br />
{<br />
    m_socketdevice = new QSocketDevice();<br />
    m_socketdevice-&#62;setAddressReusable(true);<br />
    m_socketdevice-&#62;setBlocking(true);</p>
<p>    m_buf = new char[m_bufLen];<br />
}</p>
<p>MySocket::~MySocket()<br />
{<br />
    stop();</p>
<p>    delete m_socketdevice;<br />
    m_socketdevice = 0;</p>
<p>    delete [] m_buf;<br />
    m_buf = 0;<br />
}</p>
<p>void MySocket::setId(const QString&#38; id)<br />
{<br />
    m_myId = id;<br />
}</p>
<p>void MySocket::stop()<br />
{<br />
    if (m_running)<br />
    {<br />
        m_running = false;<br />
    }<br />
    if (m_socketdevice)<br />
        m_socketdevice-&#62;close();<br />
    //wait(500);<br />
    qDebug(&#8220;MySocket::stop&#8221;);<br />
}</p>
<p>bool MySocket::connectTo(const QString&#38; serverAddr, int port)<br />
{<br />
    m_amIClient = true;<br />
    if (!m_socketdevice)<br />
        return false;</p>
<p>    bool ok = m_socketdevice-&#62;connect(serverAddr, port);<br />
    wait(1000);<br />
    if (ok)<br />
    {<br />
        QString handshake = &#8220;myid=&#8221; + m_myId;<br />
        send(handshake);<br />
    }<br />
    return ok;<br />
}</p>
<p>void MySocket::setSocket(int socket)<br />
{<br />
    m_amIClient = false;<br />
    m_socketdevice-&#62;setSocket(socket, QSocketDevice::Stream);<br />
}</p>
<p>bool MySocket::hasError()<br />
{<br />
    if (!m_socketdevice)<br />
        return true;<br />
    return (m_socketdevice-&#62;error() != QSocketDevice::NoError);<br />
}</p>
<p>void MySocket::run()<br />
{<br />
    m_running = true;</p>
<p>    if (m_socketdevice)<br />
    {<br />
        qDebug(&#8220;port/peerPort = %d,%d&#8221;, m_socketdevice-&#62;port(), m_socketdevice-&#62;peerPort());<br />
    }</p>
<p>    int len = 0;<br />
    int readLen = 0;<br />
    while (m_running &#38;&#38; m_socketdevice &#38;&#38; !hasError())<br />
    {<br />
        len = m_socketdevice-&#62;bytesAvailable();<br />
        if (len &#62; 0)<br />
        {<br />
            if (len &#62; m_bufLen)<br />
            {<br />
                m_bufLen = len;<br />
                delete [] m_buf;<br />
                m_buf = new char[m_bufLen];<br />
            }</p>
<p>            readLen = m_socketdevice-&#62;readBlock(m_buf, len);<br />
            if (readLen &#60;= 0) //error<br />
            {<br />
                qDebug(&#8220;&#8212;&#8211; read error &#8212; 1&#8243;);<br />
                m_running = false;<br />
                break;<br />
            }<br />
            while (readLen &#60; len &#38;&#38; !hasError())<br />
            {<br />
                int curLen = m_socketdevice-&#62;readBlock(m_buf + readLen, len &#8211; readLen);<br />
                if (curLen &#60;= 0) //error<br />
                {<br />
                    qDebug(&#8220;&#8212;&#8211; read error &#8212; 3&#8243;);<br />
                    m_running = false;<br />
                    break;<br />
                }<br />
                readLen += curLen;<br />
            }<br />
            if (!m_running)<br />
                break;</p>
<p>            QByteArray ba(len);<br />
            const char *data = ba.data();<br />
            memcpy(ba.data(), m_buf, len);<br />
            if (len &#62; 5 &#38;&#38; data[0] == &#8216;m&#8217; &#38;&#38; data[1] == &#8216;y&#8217; &#38;&#38; data[2] == &#8216;i&#8217; &#38;&#38; data[3] == &#8216;d&#8217; &#38;&#38; data[4] == &#8216;=&#8217;)<br />
            {<br />
                QString handshake(ba);<br />
                QString hisId = handshake.mid(5);<br />
                emit fireReceivedHandshake(m_socketdevice-&#62;socket(), hisId);<br />
            }<br />
            else if (len &#62; 3 &#38;&#38; data[0] == &#8216;c&#8217; &#38;&#38; data[1] == &#8216;m&#8217; &#38;&#38; data[2] == &#8216;d&#8217; &#38;&#38; data[3] == &#8216;Q&#8217;)<br />
            {<br />
                m_running = false;<br />
                qDebug(&#8220;MySocket::run() got cmdQ&#8221;);<br />
                emit fireReceivedData(ba);<br />
            }<br />
            else<br />
                emit fireReceivedData(ba);<br />
        }<br />
        else<br />
        {<br />
            len = m_socketdevice-&#62;waitForMore(100);<br />
            if (len == -1 &#124;&#124; hasError()) //error<br />
            {<br />
                qDebug(&#8220;&#8212;&#8211; read error &#8212; 2&#8243;);<br />
                m_running = false;<br />
                break;<br />
            }<br />
        }<br />
    }//while()<br />
    qDebug(&#8220;&#8212;&#8211; done MySocket::run() &#8212;-&#8221;);<br />
}//run()</p>
<p>bool MySocket::send(const QByteArray&#38; ba)<br />
{<br />
    bool success = false;<br />
    if (!m_socketdevice)<br />
        return success;</p>
<p>    const char *data = ba.data();<br />
    int len = ba.size();<br />
    int writtenLen = 0;</p>
<p>   <br />
    writtenLen = m_socketdevice-&#62;writeBlock(data, len);<br />
    while (writtenLen &#60; len)<br />
    {<br />
        writtenLen += m_socketdevice-&#62;writeBlock(data + writtenLen, len &#8211; writtenLen);<br />
    }</p>
<p>    return (writtenLen == len);<br />
}</p>
<p>bool MySocket::send(const QString&#38; str)<br />
{<br />
    QCString cstr = str.utf8();<br />
    const char *data = (const char *)(cstr);<br />
    QByteArray ba(cstr.length());<br />
    memcpy(ba.data(), data, cstr.length());</p>
<p>    return send(ba);<br />
}<br />
//=====================================================<br />
MyServerSocket::MyServerSocket(Q_UINT16 port)<br />
               :QServerSocket(port),<br />
                m_mysocketDict(), //key=socket(int)<br />
                m_map() //socket(int), id(Qstring)<br />
{<br />
    m_mysocketDict.setAutoDelete(true);<br />
}</p>
<p>MyServerSocket::~MyServerSocket()<br />
{<br />
    m_mysocketDict.clear();<br />
    m_map.clear();<br />
}</p>
<p>void MyServerSocket::newConnection(int socket)<br />
{<br />
    MySocket *mysocket = new MySocket();<br />
    connect(mysocket, SIGNAL(fireReceivedData(const QByteArray&#38;)),<br />
                      SIGNAL(fireReceivedData(const QByteArray&#38;)));<br />
    connect(mysocket, SIGNAL(fireReceivedHandshake(int, const QString&#38;)),<br />
                      SLOT(slotReceivedHandshake(int, const QString&#38;)));<br />
    m_map.insert(socket, QString(&#8220;&#8221;));<br />
    m_mysocketDict.insert(QString::number(socket), mysocket);<br />
    mysocket-&#62;setSocket(socket);<br />
    mysocket-&#62;start();<br />
}</p>
<p>bool MyServerSocket::send(const QByteArray&#38; ba, const QString&#38; _id)<br />
{<br />
    QMap&#60;int, QString&#62;::Iterator it;<br />
    for (it = m_map.begin(); it != m_map.end(); ++it)<br />
    {<br />
        int key = it.key();<br />
        QString id = it.data();<br />
        if (id == _id) //found it<br />
        {<br />
            MySocket *sock = m_mysocketDict.find(QString::number(key));<br />
            if (sock)<br />
            {<br />
                return sock-&#62;send(ba);<br />
            }<br />
        }<br />
    }<br />
    return false;<br />
}</p>
<p>bool MyServerSocket::send(const QString&#38; str, const QString&#38; _id)<br />
{<br />
    QMap&#60;int, QString&#62;::Iterator it;<br />
    for (it = m_map.begin(); it != m_map.end(); ++it)<br />
    {<br />
        int key = it.key();<br />
        QString id = it.data();<br />
        if (id == _id) //found it<br />
        {<br />
            MySocket *sock = m_mysocketDict.find(QString::number(key));<br />
            if (sock)<br />
            {<br />
                return sock-&#62;send(str);<br />
            }<br />
        }<br />
    }<br />
    return false;<br />
}</p>
<p>void MyServerSocket::stop()<br />
{<br />
    QDictIterator&#60;MySocket&#62; it(m_mysocketDict);<br />
    MySocket *sock = 0;<br />
    for ( ; (sock = it.current()); ++it)<br />
    {<br />
        sock-&#62;stop();<br />
    }<br />
}</p>
<p>void MyServerSocket::slotReceivedHandshake(int socket, const QString&#38; hisId)<br />
{<br />
    qDebug(&#8220;&#8212;- receive handshake :&#8221; + QString::number(socket) + &#8221; =&#8221; + hisId);<br />
    m_map.insert(socket, hisId, true);<br />
    MySocket *sock = m_mysocketDict.find(QString::number(socket));<br />
    if (sock)<br />
    {<br />
        sock-&#62;setId(hisId);<br />
        emit fireReceivedHandshake(hisId);<br />
    }<br />
}</p>
<p>&#160;</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[AIMP 2.60.505 RC1]]></title>
<link>http://netvietnam.org/2009/10/05/aimp-2-60-505-rc1/</link>
<pubDate>Mon, 05 Oct 2009 16:42:32 +0000</pubDate>
<dc:creator>Nhân Mã</dc:creator>
<guid>http://netvietnam.org/2009/10/05/aimp-2-60-505-rc1/</guid>
<description><![CDATA[AIMP là trình chơi nhạc mạnh mẽ cho phép bạn nghe những bài nhạc yêu thích với chất lượng âm thanh v]]></description>
<content:encoded><![CDATA[AIMP là trình chơi nhạc mạnh mẽ cho phép bạn nghe những bài nhạc yêu thích với chất lượng âm thanh v]]></content:encoded>
</item>
<item>
<title><![CDATA[Foobar2000 0.9.6.9]]></title>
<link>http://netvietnam.org/2009/08/24/foobar2000-0-9-6-9/</link>
<pubDate>Mon, 24 Aug 2009 00:33:39 +0000</pubDate>
<dc:creator>Nhân Mã</dc:creator>
<guid>http://netvietnam.org/2009/08/24/foobar2000-0-9-6-9/</guid>
<description><![CDATA[Foobar 2k là Soft nghe nhạc nhẹ nhàng. Nghe được nhiều định dạng File, có mã nguồn mở, chỉnh tùy ý t]]></description>
<content:encoded><![CDATA[Foobar 2k là Soft nghe nhạc nhẹ nhàng. Nghe được nhiều định dạng File, có mã nguồn mở, chỉnh tùy ý t]]></content:encoded>
</item>
<item>
<title><![CDATA[Foobar2000 0.9.6.9 beta 1]]></title>
<link>http://netvietnam.org/2009/08/12/foobar2000-0-9-6-9-beta-1/</link>
<pubDate>Wed, 12 Aug 2009 03:14:17 +0000</pubDate>
<dc:creator>Nhân Mã</dc:creator>
<guid>http://netvietnam.org/2009/08/12/foobar2000-0-9-6-9-beta-1/</guid>
<description><![CDATA[Foobar 2k là Soft nghe nhạc nhẹ nhàng. Nghe được nhiều định dạng File, có mã nguồn mở, chỉnh tùy ý t]]></description>
<content:encoded><![CDATA[Foobar 2k là Soft nghe nhạc nhẹ nhàng. Nghe được nhiều định dạng File, có mã nguồn mở, chỉnh tùy ý t]]></content:encoded>
</item>
<item>
<title><![CDATA[AIMP 2.60.462 Beta 2]]></title>
<link>http://netvietnam.org/2009/07/13/aimp-2-60-462-beta-2/</link>
<pubDate>Mon, 13 Jul 2009 13:08:21 +0000</pubDate>
<dc:creator>Nhân Mã</dc:creator>
<guid>http://netvietnam.org/2009/07/13/aimp-2-60-462-beta-2/</guid>
<description><![CDATA[AIMP là trình chơi nhạc mạnh mẽ cho phép bạn nghe những bài nhạc yêu thích với chất lượng âm thanh v]]></description>
<content:encoded><![CDATA[AIMP là trình chơi nhạc mạnh mẽ cho phép bạn nghe những bài nhạc yêu thích với chất lượng âm thanh v]]></content:encoded>
</item>
<item>
<title><![CDATA[Core Player v1.30 for Symbian S60v3]]></title>
<link>http://mobileshouse.wordpress.com/2009/07/12/core-player-v1-30-for-symbian-s60v3/</link>
<pubDate>Sun, 12 Jul 2009 19:29:04 +0000</pubDate>
<dc:creator>saboor38</dc:creator>
<guid>http://mobileshouse.wordpress.com/2009/07/12/core-player-v1-30-for-symbian-s60v3/</guid>
<description><![CDATA[CorePlayer is designed to be a next-generation multimedia platform that will extend upon what you th]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p style="text-align:center;"><img class="alignnone" title="core" src="http://www.everythingtreo.com/images/stories/coreplayer/coreplayer5.jpg" alt="" width="340" height="340" /></p>
<p style="text-align:center;"><span><span>CorePlayer is <span>designed</span><span> to be a next-generation <span>multimedia</span> platform that will extend upon what you thought were limits in playing back fluid multiemdia , with its simple yet extremely powerful </span></span><span>interface</span><span>and features that is designed to empower the CoreCodec Community.</span></span></p>
<p><span><span>See why companies like Joost, SanDisk, DivX, Elgato and more are using CoreCodec <span>technology</span> and why the Chicago Suntimes times says that CorePlayer, “actually has a user </span>interface<span> <span>designed</span> with bipeds in mind.”</span></span></p>
<p><strong>Technology <span>Overview:</span></strong><br />
* H.264 Ready with CoreAVC<br />
* Built-In YouTube Support<br />
* Flash/FLV Container Support<br />
* Bluetooth ready!* (A2DP and AVRCP)<br />
* Supports over 22 Languages (20+ more coming soon!)<br />
* Podcast, Enhanced Podcast, CoreCaster Ready<br />
<span>* CoreUI ‘Universal skins’ Widget. Allows you to create a unique custom user <span>interface</span> exactly how you want it!</span><br />
<span><span>* Best in Class <span style="text-decoration:underline;">audio and video</span><span> codecs like CoreAVC our <span style="text-decoration:underline;">High Definition</span> H.264 video decoder</span></span></span><br />
* CoreTheque media library allows for easy management of your playlists and bookmarks</p>
<p style="text-align:center;"><!--more--><strong><em>Download Link :</em></strong><a href="http://www.ziddu.com/download/5580695/coreplayerMobilesHouse.blogspot.com.rar.html"> Core Player</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Core Player v1.30 for Symbian S60v3]]></title>
<link>http://saboor38.wordpress.com/2009/07/12/core-player-v1-30-for-symbian-s60v3/</link>
<pubDate>Sun, 12 Jul 2009 19:29:03 +0000</pubDate>
<dc:creator>saboor38</dc:creator>
<guid>http://saboor38.wordpress.com/2009/07/12/core-player-v1-30-for-symbian-s60v3/</guid>
<description><![CDATA[CorePlayer is designed to be a next-generation multimedia platform that will extend upon what you th]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p style="text-align:center;"><img class="alignnone" title="core" src="http://www.everythingtreo.com/images/stories/coreplayer/coreplayer5.jpg" alt="" width="340" height="340" /></p>
<p style="text-align:center;"><span><span>CorePlayer is <span>designed</span><span> to be a next-generation <span>multimedia</span> platform that will extend upon what you thought were limits in playing back fluid multiemdia , with its simple yet extremely powerful </span></span><span>interface</span><span>and features that is designed to empower the CoreCodec Community.</span></span></p>
<p><span><span>See why companies like Joost, SanDisk, DivX, Elgato and more are using CoreCodec <span>technology</span> and why the Chicago Suntimes times says that CorePlayer, “actually has a user </span>interface<span> <span>designed</span> with bipeds in mind.”</span></span></p>
<p><strong>Technology <span>Overview:</span></strong><br />
* H.264 Ready with CoreAVC<br />
* Built-In YouTube Support<br />
* Flash/FLV Container Support<br />
* Bluetooth ready!* (A2DP and AVRCP)<br />
* Supports over 22 Languages (20+ more coming soon!)<br />
* Podcast, Enhanced Podcast, CoreCaster Ready<br />
<span>* CoreUI ‘Universal skins’ Widget. Allows you to create a unique custom user <span>interface</span> exactly how you want it!</span><br />
<span><span>* Best in Class <span style="text-decoration:underline;">audio and video</span><span> codecs like CoreAVC our <span style="text-decoration:underline;">High Definition</span> H.264 video decoder</span></span></span><br />
* CoreTheque media library allows for easy management of your playlists and bookmarks</p>
<p style="text-align:center;"><!--more--><strong><em>Download Link :</em></strong><a href="http://www.ziddu.com/download/5580695/coreplayerMobilesHouse.blogspot.com.rar.html"> Core Player</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Core Player v1.30 for Symbian S60v3]]></title>
<link>http://mobiman.wordpress.com/2009/07/12/core-player-v1-30-for-symbian-s60v3/</link>
<pubDate>Sun, 12 Jul 2009 09:23:07 +0000</pubDate>
<dc:creator>mobiman</dc:creator>
<guid>http://mobiman.wordpress.com/2009/07/12/core-player-v1-30-for-symbian-s60v3/</guid>
<description><![CDATA[CorePlayer is designed to be a next-generation multimedia platform that will extend upon what you th]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><img title="CoreCodec CorePlayer v1.30 (S60v3)" src="http://i212.photobucket.com/albums/cc94/Dl4All/album4/CorePlayer.jpg" alt="CoreCodec CorePlayer v1.30 (S60v3)" /><br />
CorePlayer is designed to be a next-generation multimedia platform that will extend upon what you thought were limits in playing back fluid multimedia, with its simple yet extremely powerful interface and features that is designed to empower the CoreCodec Community.</p>
<p>See why companies like Joost, SanDisk, DivX, Elgato and more are using CoreCodec technology and why the Chicago Suntimes times says that CorePlayer, &#8220;actually has a user interface designed with bipeds in mind.&#8221;</p>
<p>Technology Overview:<br />
* H.264 Ready with CoreAVC<br />
* Built-In YouTube Support<br />
* Flash/FLV Container Support<br />
* Bluetooth ready!* (A2DP and AVRCP)<br />
* Supports over 22 Languages (20+ more coming soon!)<br />
* Podcast, Enhanced Podcast, CoreCaster Ready<br />
* CoreUI &#8216;Universal skins&#8217; Widget. Allows you to create a unique custom user interface exactly how you want it!<br />
* Best in Class audio and video codecs like CoreAVC our High Definition H.264 video decoder<br />
* CoreTheque media library allows for easy management of your playlists and bookmarks</p>
<p>Audio Formats:<br />
MP3, MP2, AAC, MKA, WMA, Midi*, WAV, OGG, Speex, WAVPACK, TTA, FLAC, MPC, AMR, ADPCM, ALaw, MuLaw, G.729, GSM</p>
<p>Video Formats:<br />
H.264 (AVC), AVCHD, MKV, MPEG-1, MPEG-4 part 2 (ASP), DivX, XviD, WMV*, Theora*, Dirac*, MJPEG, MSVIDEO1</p>
<p>Image Formats:<br />
JPEG (420, 422, 440, EXIF Headers)*, BMP, GIF, PNG, TIFF, MJPEG</p>
<p>Container Formats:<br />
Flash/FLV, Matroska, ASF, ASX, AVI, PS, M2TS, TS, 3GPP, MOV,MPEG-4, OGM, NSV</p>
<p>Streaming Formats:<br />
HTTP, UDP, UDP Multicast, UDP Unicast, RDP, RTP. RTSP, RTCP(keep alive), ASX, ASF, Multicast, HTTP Tunneling</p>
<p>Additional Features:<br />
Google Data, Benchmarking, Integrated Pocket IE/IE Support, SMB Browsing</p>
<p>Compatibility:<br />
For Symbian 9.1/9.2/9.3 (S60v3) mobiles like N73, N76, N81, N81 8GB, N82, N95, N95 8GB, etc.</p>
<p><a href="http://www.ziddu.com/download/5574226/CorePlayerS60v3.rar.html">Download: 2MB</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Foobar2000 9.6.8 Music Player]]></title>
<link>http://filemirrors.wordpress.com/2009/06/10/foobar2000-9-6-8-music-player/</link>
<pubDate>Wed, 10 Jun 2009 14:14:30 +0000</pubDate>
<dc:creator>filemirrors</dc:creator>
<guid>http://filemirrors.wordpress.com/2009/06/10/foobar2000-9-6-8-music-player/</guid>
<description><![CDATA[Foobar2000 is an advanced freeware audio player for the Windows platform. Some of the basic features]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><img src="http://filemirrors.wordpress.com/files/2009/05/foobar-music-player.png" alt="foobar-music-player" title="foobar-music-player" width="680" height="572" class="alignnone size-full wp-image-315" /></p>
<p>Foobar2000 is an advanced freeware audio player for the Windows platform. Some of the basic features include full unicode support, ReplayGain support and native support for several popular audio formats. The foobar2000 player supports the following audio formats: MP3, MP4, AAC, CD Audio, WMA, Vorbis, FLAC, WavPack, WAV, AIFF, Musepack, Speex, AU, SND and even more with the help of additional components. One of the biggest advantages of the player is the open component architecture allowing third-party developers to extend functionality of the player. With foobar2000 you also get support for gapless playback, easily customizable user interface layout, advanced tagging capabilities, support for ripping Audio CDs as well as transcoding all supported audio formats using the Converter component and even more&#8230;</p>
<p>- <a href="http://uploading.com/files/I0CHUGYI/foobar2000_0.9.6.8.zip.html" target="_blank"><b>Download Foobar2000 9.6.8 Music Player</b></a><br />
- <a href="http://saveqube.com/getfile/02183730acddc8f04e9b690b951718d33b676a927e72a3df53/foobar2000_0.9.6.8.zip.html" target="_blank"><b>Download Foobar2000 9.6.8 Music Player (mirror 1)</b></a><br />
- <a href="http://www.easy-share.com/1905634468/foobar2000_0.9.6.8.zip" target="_blank"><b>Download Foobar2000 9.6.8 Music Player (mirror 2)</b></a><br />
- <a href="http://sharingmatrix.com/file/161241/foobar2000_0.9.6.8.zip" target="_blank"><b>Download Foobar2000 9.6.8 Music Player (mirror 3)</b></a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Foobar2000 0.9.6.7]]></title>
<link>http://netvietnam.org/2009/05/22/foobar2000-0-9-6-7/</link>
<pubDate>Fri, 22 May 2009 10:18:15 +0000</pubDate>
<dc:creator>Nhân Mã</dc:creator>
<guid>http://netvietnam.org/2009/05/22/foobar2000-0-9-6-7/</guid>
<description><![CDATA[Foobar 2k là Soft nghe nhạc nhẹ nhàng. Nghe được nhiều định dạng File, có mã nguồn mở, chỉnh tùy ý t]]></description>
<content:encoded><![CDATA[Foobar 2k là Soft nghe nhạc nhẹ nhàng. Nghe được nhiều định dạng File, có mã nguồn mở, chỉnh tùy ý t]]></content:encoded>
</item>
<item>
<title><![CDATA[Foobar2000 0.9.6.6]]></title>
<link>http://netvietnam.org/2009/05/18/foobar2000-0-9-6-6/</link>
<pubDate>Mon, 18 May 2009 09:36:10 +0000</pubDate>
<dc:creator>Nhân Mã</dc:creator>
<guid>http://netvietnam.org/2009/05/18/foobar2000-0-9-6-6/</guid>
<description><![CDATA[Foobar 2k là Soft nghe nhạc nhẹ nhàng. Nghe được nhiều định dạng File, có mã nguồn mở, chỉnh tùy ý t]]></description>
<content:encoded><![CDATA[Foobar 2k là Soft nghe nhạc nhẹ nhàng. Nghe được nhiều định dạng File, có mã nguồn mở, chỉnh tùy ý t]]></content:encoded>
</item>
<item>
<title><![CDATA[Foobar2000 9.6.5 Music Player]]></title>
<link>http://filemirrors.wordpress.com/2009/05/11/foobar2000-9-6-5-music-player/</link>
<pubDate>Mon, 11 May 2009 10:45:39 +0000</pubDate>
<dc:creator>filemirrors</dc:creator>
<guid>http://filemirrors.wordpress.com/2009/05/11/foobar2000-9-6-5-music-player/</guid>
<description><![CDATA[foobar2000 is an advanced freeware audio player for the Windows platform. Some of the basic features]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><img src="http://filemirrors.wordpress.com/files/2009/05/foobar-music-player.png" alt="foobar-music-player" title="foobar-music-player" width="680" height="572" class="alignnone size-full wp-image-315" /></p>
<p>foobar2000 is an advanced freeware audio player for the Windows platform. Some of the basic features include full unicode support, ReplayGain support and native support for several popular audio formats. The foobar2000 player supports the following audio formats: MP3, MP4, AAC, CD Audio, WMA, Vorbis, FLAC, WavPack, WAV, AIFF, Musepack, Speex, AU, SND and even more with the help of additional components. One of the biggest advantages of the player is the open component architecture allowing third-party developers to extend functionality of the player. With foobaer2000 you also get support for gapless playback, easily customizable user interface layout, advanced tagging capabilities, support for ripping Audio CDs as well as transcoding all supported audio formats using the Converter component and even more&#8230;</p>
<p>- <a href="http://uploading.com/files/C2SSN0YA/foobar2000_0.9.6.5.exe.html" target="_blank"><b>Download Foobar2000 9.6.5 Music Player</b></a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Foobar2000 0.9.6.6 beta 1]]></title>
<link>http://netvietnam.org/2009/05/09/foobar2000-0-9-6-6-beta-1/</link>
<pubDate>Sat, 09 May 2009 13:47:29 +0000</pubDate>
<dc:creator>Nhân Mã</dc:creator>
<guid>http://netvietnam.org/2009/05/09/foobar2000-0-9-6-6-beta-1/</guid>
<description><![CDATA[Foobar 2k là Soft nghe nhạc nhẹ nhàng. Nghe được nhiều định dạng File, có mã nguồn mở, chỉnh tùy ý t]]></description>
<content:encoded><![CDATA[Foobar 2k là Soft nghe nhạc nhẹ nhàng. Nghe được nhiều định dạng File, có mã nguồn mở, chỉnh tùy ý t]]></content:encoded>
</item>
<item>
<title><![CDATA[Foobar2000 0.9.6.5]]></title>
<link>http://netvietnam.org/2009/04/28/foobar2000-0965/</link>
<pubDate>Tue, 28 Apr 2009 05:39:33 +0000</pubDate>
<dc:creator>Nhân Mã</dc:creator>
<guid>http://netvietnam.org/2009/04/28/foobar2000-0965/</guid>
<description><![CDATA[Foobar 2k là Soft nghe nhạc nhẹ nhàng. Nghe được nhiều định dạng File, có mã nguồn mở, chỉnh tùy ý t]]></description>
<content:encoded><![CDATA[Foobar 2k là Soft nghe nhạc nhẹ nhàng. Nghe được nhiều định dạng File, có mã nguồn mở, chỉnh tùy ý t]]></content:encoded>
</item>
<item>
<title><![CDATA[Foobar2000 0.9.6.5 beta 2]]></title>
<link>http://netvietnam.org/2009/04/21/foobar2000-0965-beta-2/</link>
<pubDate>Tue, 21 Apr 2009 01:03:41 +0000</pubDate>
<dc:creator>Nhân Mã</dc:creator>
<guid>http://netvietnam.org/2009/04/21/foobar2000-0965-beta-2/</guid>
<description><![CDATA[Foobar 2k là Soft nghe nhạc nhẹ nhàng. Nghe được nhiều định dạng File, có mã nguồn mở, chỉnh tùy ý t]]></description>
<content:encoded><![CDATA[Foobar 2k là Soft nghe nhạc nhẹ nhàng. Nghe được nhiều định dạng File, có mã nguồn mở, chỉnh tùy ý t]]></content:encoded>
</item>
<item>
<title><![CDATA[AIMP 2.60.462 Beta 1]]></title>
<link>http://netvietnam.org/2009/04/13/aimp-260462-beta-1/</link>
<pubDate>Mon, 13 Apr 2009 14:15:33 +0000</pubDate>
<dc:creator>Nhân Mã</dc:creator>
<guid>http://netvietnam.org/2009/04/13/aimp-260462-beta-1/</guid>
<description><![CDATA[AIMP là trình chơi nhạc mạnh mẽ cho phép bạn nghe những bài nhạc yêu thích với chất lượng âm thanh v]]></description>
<content:encoded><![CDATA[AIMP là trình chơi nhạc mạnh mẽ cho phép bạn nghe những bài nhạc yêu thích với chất lượng âm thanh v]]></content:encoded>
</item>
<item>
<title><![CDATA[Try RTMFP and Client-to-Client Direct Streaming, using FlashPlayer10 and Cocomo]]></title>
<link>http://arunbluebrain.wordpress.com/2008/12/08/try-rtmfp-and-client-to-client-direct-streaming-using-flashplayer10-and-cocomo/</link>
<pubDate>Mon, 08 Dec 2008 11:36:44 +0000</pubDate>
<dc:creator>arunbluebrain</dc:creator>
<guid>http://arunbluebrain.wordpress.com/2008/12/08/try-rtmfp-and-client-to-client-direct-streaming-using-flashplayer10-and-cocomo/</guid>
<description><![CDATA[One of my favorite features in Flash Player 10 is the ability to stream live audio/video via RTMFP, ]]></description>
<content:encoded><![CDATA[One of my favorite features in Flash Player 10 is the ability to stream live audio/video via RTMFP, ]]></content:encoded>
</item>
<item>
<title><![CDATA[Techninieks luvz Gyroballz]]></title>
<link>http://nwitha.wordpress.com/2008/11/14/techninieks-luvz-gyroballz/</link>
<pubDate>Fri, 14 Nov 2008 15:15:19 +0000</pubDate>
<dc:creator>woozers</dc:creator>
<guid>http://nwitha.wordpress.com/2008/11/14/techninieks-luvz-gyroballz/</guid>
<description><![CDATA[]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><span style='text-align:center; display: block;'><object width='425' height='350'><param name='movie' value='http://www.youtube.com/v/LTfY1phDYak&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;hd=0' /><param name='allowfullscreen' value='true' /><param name='wmode' value='transparent' /><embed src='http://www.youtube.com/v/LTfY1phDYak&#038;rel=1&#038;fs=1&#038;showsearch=0&#038;hd=0' type='application/x-shockwave-flash' allowfullscreen='true' width='425' height='350' wmode='transparent'></embed></object></span></p>
<p> <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Convertir des fichiers ogg ou speex en mp3]]></title>
<link>http://blacherez.wordpress.com/2008/10/06/convertir-des-fichiers-ogg-ou-speex-en-mp3/</link>
<pubDate>Mon, 06 Oct 2008 11:22:29 +0000</pubDate>
<dc:creator>blacherez</dc:creator>
<guid>http://blacherez.wordpress.com/2008/10/06/convertir-des-fichiers-ogg-ou-speex-en-mp3/</guid>
<description><![CDATA[Je me suis trouvé souvent dans le situation de vouloir écouter des fichiers audio sur un appareil qu]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Je me suis trouvé souvent dans le situation de vouloir écouter des fichiers audio sur un appareil qui ne connaissait pas le format utilisé (le plus souvent <a href="http://fr.wikipedia.org/wiki/Ogg">Ogg</a> ou <a href="http://fr.wikipedia.org/wiki/Speex">Speex</a>). Tous les appareils lisent le MP3 en revanche. J&#8217;ai donc voulu trouver un utilitaire pour faire la conversion.</p>
<p>Pour convertir des fichiers ogg en mp3, tout est expliqué <a href="http://www.axul.org/documentation/convertir-des-ogg-en-mp3">ici</a>. Pour les speex (extension .spx), le principe est le même, mais en utilisant la commande speexdec au lieu de oggdec afin de convertir le fichier en wav (la syntaxe est un tout petit peu différente).</p>
<p>Note : Je suis sous Linux, mais on doit pouvoir faire fonctionner ce script sous Windows avec Cygwin.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Ownijs owno]]></title>
<link>http://woozers.wordpress.com/2008/07/29/ownijs-owno/</link>
<pubDate>Tue, 29 Jul 2008 10:37:37 +0000</pubDate>
<dc:creator>woozers</dc:creator>
<guid>http://woozers.wordpress.com/2008/07/29/ownijs-owno/</guid>
<description><![CDATA[(13:06:37) » Join: Ownijs (~no@87.110.144.163) (13:06:39) Ownijs: URLAS KROPLI, MAUKAS BLEE!!!! nosp]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>(13:06:37) » Join: Ownijs (~no@87.110.144.163)<br />
(13:06:39) Ownijs: URLAS KROPLI, MAUKAS BLEE!!!! nosprāgstiet kukainji tizlie!!!!<br />
(13:06:40) » Part: Ownijs (~no@87.110.144.163)</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[P2P in Flash 10 Beta - a YouTube, Skype, and BitTorrent Killer]]></title>
<link>http://adamfisk.wordpress.com/2008/05/16/p2p-in-flash-10-beta-a-youtube-skype-and-bittorrent-killer/</link>
<pubDate>Fri, 16 May 2008 22:59:24 +0000</pubDate>
<dc:creator>adamfisk</dc:creator>
<guid>http://adamfisk.wordpress.com/2008/05/16/p2p-in-flash-10-beta-a-youtube-skype-and-bittorrent-killer/</guid>
<description><![CDATA[The inclusion of p2p in the Flash 10 beta threatens to bring down everyone from YouTube to Skype. Us]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>The inclusion of p2p in the <a title="Flash 10 Beta" href="http://labs.adobe.com/technologies/flashplayer10/">Flash 10 beta</a> threatens to bring down everyone from YouTube to Skype.  Using P2P, Flash sites will be able to serve higher quality video than YouTube at a fraction of the cost.  Meanwhile, the combination of the Speex audio codec and the Real Time Media Flow Protocol (RTMFP) will enable sites to seamlessly integrate VoIP without requiring a Skype install.  The impact of this change is hard to fathom.  We&#8217;re talking about a fundamental shift in what is possible on the Internet, with Flash demolishing almost all barriers to integrating P2P on any site.</p>
<p><a title="Hank Williams p2p" href="http://whydoeseverythingsuck.com/2008/05/flash-10-p2p-and-cdns-deeper-analysis.html">Hank Williams</a> and <a title="gigaom" href="http://gigaom.com/2008/05/15/flash-p2p-now-thats-disruptive/">Om Malik</a> have discussed the potential for Flash 10 to be used for P2P CDNs, and they&#8217;re largely right on.  The biggest problem I see with P2P CDNs is oddly latency, however.  While P2P theoretically enables you to choose copies of content closer to you on the network, you still have to negotiate with a server somewhere to establish the connection (for traversing NATs), nullifying the P2P advantage unless you&#8217;re talking about really big files.  As Hank identifies, the sites serving large files are the CDN&#8217;s best customers, so we are talking about a significant chunk of the CDN business up for grabs.  That said, CDNs could easily start running Flash Media Servers themselves with integrated RTMFP.  They&#8217;ve already addressed the server locality problem, and taking advantage of Flash deployments would simply be an optimization.  Whether the CDNs will realize this shift has taken place before it&#8217;s too late is another question.</p>
<p>To me, the really vulnerable players are the video sites themselves and anyone in the client-side VoIP space.  Writing a VoIP app is now equivalent to writing your own Flash video player.  All the hard stuff is already done.  Same with serving videos.  You no longer have to worry about setting up an infinitely scalable server cluster &#8212; you just offload everything to Flash.  No more heavy lifting and no more huge bandwidth bills.  In the BitTorrent case, it&#8217;s mostly a matter of usability.  As with Skype, you no longer need a separate install.  Depending on what&#8217;s built in to the Flash Media Server, you also no longer need to worry about complicated changes on the server side, and downloads will happen right in the browser.</p>
<p>The stunning engineering behind all of this should be adequately noted.  The Real Time Media Flow Protocol (RTMFP) underlies all of these changes.  On closer inspection, RTMFP appears to be the latest iteration of Matthew Kaufman and Michael Thornburgh&#8217;s <a title="Secure Media Flow Protocol" href="http://web.archive.org/web/20060211083929/www.amicima.com/downloads/documentation/protocol-doc-20051216.txt">Secure Media Flow Protocol (SMP)</a> from Adobe&#8217;s 2006 acquisition of Amicima. Adobe appears to have acquired Amicima specifically to integrate SMP into Flash, now in the improved form of RTMFP.  This is a very fast media transfer protocol built on UDP with IPSec-like security and congestion control  built in.  The strength of the protocol was clear to me when Matthew first posted his<a title="Matthew Kaufman SMP" href="http://zgp.org/pipermail/p2p-hackers/2005-July/002801.html"> &#8220;preannouncement&#8221;</a> on the p2p hackers list.  Very shrewd move on Adobe&#8217;s part.</p>
<p>Are there any downsides? Well, RTMFP, is for now a closed if breathtakingly cool protocol, and it&#8217;s tied to Flash Media Server. That means Adobe holds all the cards, and this isn&#8217;t quite the open media platform to end all platforms. If they open up the protocol and open source implementations start emerging, however, the game&#8217;s over.</p>
<p>Not that I have much sympathy, but this will also shift a huge amount of traffic to ISPs, as ISPs effectively take the place of CDNs without getting paid for it.  While Flash could implement the emerging <a title="p4p" href="http://en.wikipedia.org/wiki/Proactive_network_Provider_Participation_for_P2P">P4P standards</a> to limit the bleeding at the ISPs and to further improve performance, this will otherwise eventually result in higher bandwidth bills for consumers over the long term.  No matter &#8212; I&#8217;d rather have us all pay a little more in exchange for dramatically increasing the numbers of people who can set up high bandwidth sites on the Internet.  The free speech implications are too good to pass up.</p>
<p>Just to clear up some earlier confusion, Flash Beta 10 is not based on SIP or P2P-SIP in any way.  Adobe&#8217;s SIP work has so far only seen the light of day in Adobe Pacifica, but not in the Flash Player.</p>
</div>]]></content:encoded>
</item>

</channel>
</rss>
