Sending my own audio frames

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



 
Thanks alot for your source code Norman, it has been a big boost to my code development...
 
 
I am having a diferent problem now.
I can ear the sound frames i added on my sound speakers, but i am not sending them in the RTP session.
I did the following:
 
pjmedia_conf_add_port(conference_bridge, pool_vars, &port, NULL, &slot);
pjmedia_conf_connect_port(conference_bridge, slot, inSlot, 0);
 
 
I have tested putting frames on the master_port directly, and the saound frames are sent throw RTP:
 
pjmedia_port* master = pjmedia_conf_get_master_port(conference_bridge);
pjmedia_port_put_frame(master, &frame);
 
 
...but i don't think this is the proper way to do it
 
Can anyone help?
How should i send the audio frames?
 
Thanks in advance for any help....
 
 
Rafael Maia
 
 



From: norman@myasd.comTo: pjsip at lists.pjsip.orgDate: Fri, 9 Jan 2009 18:48:10 -0500Subject: Re: Sending my own audio framesYou can use pjmedia_splitcomb_create_rev_channel to reverse the put/get semantics. I do that elsewhere and it works. 

I did then add it to the conference bridge.


Sadly, my code isn't easy to extract and is very C++ using boost and a custom string library.


typedef bool (*GetSamplesPtr)(void * inBuf, uint32_t * ioByteSize, pj_timestamp * inTime);


PlayPort::PlayPort(
unsigned sampling_rate,
unsigned channel_count,
unsigned samples_per_frame,
unsigned bits_per_sample
)
: pool(NULL), mCallIndex(INVALID_CALL_INDEX)
{
    const pj_str_t name = pj_str("file");

    pool = pjsua_pool_create("asd_player", 4000, 4000);
    assert(pool);

    pj_strdup2(pool, &base.info.name, "asd_player");

    base.get_frame = &file_get_frame_get;
    base.put_frame = &file_put_frame_get;
    base.on_destroy = &file_on_destroy_get;

    pjmedia_port_info_init(&base.info, &name, SIGNATURE, sampling_rate, channel_count, bits_per_sample, samples_per_frame);

    port_is_open = true;
    options = 0;
}

PlayPort::~PlayPort()
{
    Close();

    if (pool) {
        pj_pool_release(pool);
        pool = NULL;
    }
}

pj_status_t PlayPort::Open(SInt32 inCallIndex, float inVolume, GetSamplesPtr inFunc)
{
    pj_status_t status;

    status = pjsua_conf_add_port(pool, &base, &slot);
    if (status != PJ_SUCCESS) {
        pjmedia_port_destroy(&base);
        return status;
    }

    mCallIndex = inCallIndex;

    status = pjsua_conf_adjust_rx_level(slot, inVolume);

    port_func = inFunc;

    return status;
}

void PlayPort::Close(void)
{
    file_on_destroy_get(&base);
}

bool PlayPort::IsOpen(void)
{
    return port_is_open && slot >= 0;
}

pj_status_t PlayPort::ConnectTo(int inSlot)
{
    return pjsua_conf_connect(slot, inSlot);
}

pj_status_t PlayPort::DisconnectFrom(int inSlot)
{
    return pjsua_conf_disconnect(slot, inSlot);
}

// Class static
pj_status_t PlayPort::file_on_destroy_get(pjmedia_port *this_port)
{
    // As the first element in a non-virtual class...
    PlayPort *fport = (PlayPort *) this_port;
    boost::recursive_mutex::scoped_lock l(fport->m);

    pj_assert(this_port->info.signature == SIGNATURE);

    if (fport->port_is_open) {
     fport->port_is_open = false; // Prevents a recursive callback

        fport->port_func = NULL;
        pjsua_conf_remove_port(fport->slot); // If it's already removed, e.g. audio device changed, this crashes. 
        fport->slot = 0;
        pjmedia_port_destroy(&fport->base);
    }

    return PJ_SUCCESS;
}

// Class static
pj_status_t PlayPort::file_get_frame_get(pjmedia_port *this_port, pjmedia_frame *frame)
{
    // As the first element in a non-virtual class...
    PlayPort *fport = (PlayPort *) this_port;

    pj_assert(this_port->info.signature == SIGNATURE);

    if (frame->size == 0) return PJ_SUCCESS;
    if (! fport->port_func) return PJ_EEOF;

    pj_size_t frame_size = frame->size;
    if ((*fport->port_func)(frame->buf, &frame_size, (PJSUA_Timestamp *) &frame->timestamp)) {
        if (frame_size < frame->size) {
            bzero((UInt8*)frame->buf + frame_size, frame->size - frame_size);
        }
        frame->timestamp.u64 = 0;
        frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
        return PJ_SUCCESS;
    }
    file_on_destroy_get(this_port);
    return PJ_EEOF;
}

// Class static
pj_status_t PlayPort::file_put_frame_get(pjmedia_port *this_port, const pjmedia_frame *frame)
{
    return PJ_EINVALIDOP;
}






Norman Franke
Answering Service for Directors, Inc.
www.myasd.com

On Jan 9, 2009, at 1:27 PM, Rafael Maia wrote:

 Thanks for your anwser Norman. You are using a very diferent approach from mine. Could you provide some more information ( or some source code ) ? My DirectShow sound reading routines are pushing audio frames that i need to send throw PJSIP. So i need to call put_frame on a media port.How did you created this "Passive" port ? You also add it to the conference bridge, right ? Thanks in advance... Rafael Maia 

From: norman@myasd.comTo: pjsip at lists.pjsip.orgDate: Fri, 9 Jan 2009 12:17:19 -0500Subject: Re: Sending my own audio framesI use pjmedia_port_info_init to create a player port. Something like this:


    pool = pjsua_pool_create("MyPlayerPool", 4000, 4000);
    pj_strdup2(pool, &base.info.name, "MyPlayer");

    base.get_frame = &file_get_frame_get;
    base.put_frame = &file_put_frame_get;
    base.on_destroy = &file_on_destroy_get;

    pjmedia_port_info_init(&base.info, &name, SIGNATURE, sampling_rate, channel_count, bits_per_sample, samples_per_frame);


This works well for playing files in a non-standard format that I need to support. You put your sample generation code in file_get_frame_get.




Norman Franke
Answering Service for Directors, Inc.
www.myasd.com

On Jan 9, 2009, at 9:24 AM, Rafael Maia wrote:

 Hi, i made a media player in DirectShow that captures PCM audio frames from mp3 audio files. I need to send this audio frames to PJSIP. Can anyone help me? I have tried adding a passive_port to the conference bridge and it did not worked. Now i am trying to use splitcomb. And i can send some noise. Here's a code sample: // 1? pjmedia_splitcom_createpj_status_t status = pjmedia_splitcomb_create(pool_vars, nSamplesPerSec, nChannels, samplesPerFrame, wBitsPerSample, 0, &p_splitcomb);// for each channelfor(unsigned int i = 0; i < nChannels; i++)  {     unsigned int p_slot;     pjmedia_port* p_port;      // 2? pjmedia_splitcom_create_rev_channel     status = pjmedia_splitcomb_create_rev_channel(pool_vars, p_splitcomb, i, 0, &p_port);      // 3? pjmedia_conf_add_port     status = pjmedia_conf_add_port(conference_bridge, pool_vars, p_port, NULL, &p_slot);}  And then, when i want to send an audio frame i do the following: pjmedia_port_put_frame(p_splitcomb, &frame);   What is wrong with my code?Am i using splitcom correctly? Any help would be appreciated... Rafael Maia 

O jeito mais f?cil de manter a sua lista de amigos sempre em ordem! Organize seus contatos!_______________________________________________Visit our blog: http://blog.pjsip.orgpjsip mailing listpjsip at lists.pjsip.orghttp://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org

Not?cias direto do New York Times, gols do Lance, videocassetadas e muitos outros v?deos no MSN Videos! Confira j?! _______________________________________________Visit our blog: http://blog.pjsip.orgpjsip mailing listpjsip at lists.pjsip.orghttp://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
_________________________________________________________________
Mais do que emails! Confira tudo o que Windows Live? pode oferecer.
http://www.microsoft.com/windows/windowslive/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pjsip.org/pipermail/pjsip_lists.pjsip.org/attachments/20090112/45e50e01/attachment-0001.html>


[Index of Archives]     [Asterisk Users]     [Asterisk App Development]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [Linux API]
  Powered by Linux