Sending my own audio frames

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

 



You 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@xxxxxxxxx
> To: pjsip at lists.pjsip.org
> Date: Fri, 9 Jan 2009 12:17:19 -0500
> Subject: Re: Sending my own audio frames
>
> I 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_create
> pj_status_t status = pjmedia_splitcomb_create(pool_vars,  
> nSamplesPerSec, nChannels, samplesPerFrame, wBitsPerSample, 0,  
> &p_splitcomb);
> // for each channel
> for(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.org
>
> pjsip mailing list
> pjsip at lists.pjsip.org
> http://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.org
>
> pjsip mailing list
> pjsip at lists.pjsip.org
> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pjsip.org/pipermail/pjsip_lists.pjsip.org/attachments/20090109/e8622d8b/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