Subject: [AVT] RTP SEND-RECV / Problem with linux 8.0 Sound.

From: P Lavin <[email-masked]>
Date: Fri, 15 Oct 2004 13:53:58 +0530

Hi Steve,

I've developed an RTP Stack. Now i'm doing the testing for the same.
The stack is being tested on Linux 8.0, afterwords this will be ported 
to some RTOS...
I've tested my stack with one SEND-Only session on one machine & RECV-
Only session on other machine. It worked fine !!! I was able to communi-
cate with the other endpoint using my stack(But a small delay was there).
Now i'm testing SendRecv session (ie sending and receiving in single (or 
multiple) thread)(I'll be reading/writing to /dev/dsp inside a loop)

The sequence of operations on single thread is given below,

while(1)
{
   //read from /dev/dsp.
   //Send this to n/w using RTP
   //recv data from RTP Stack.
   //Write this data to /dev/dsp
}

The problem lies here...
In this progam i'm reciving the data frm remote session correctly...and 
i'm writing that data after receiving ... but after each write the my 
audio has a delay in palying the next packet... wt i'm trying to say is 
the data from the remote machine seems to be non-contineous. Where as 
when i tried with send-only & recv-only the real-time playback was 
contineous...

I've opened the audio device using one of the files provided by vovida. 
I'm attatching that file.
Sampling rate 44100Hz, 16Bits.

Please help me with this issue...

Thanks in Advance,
Regards,
P Lavin

/* ====================================================================
 * The Vovida Software License, Version 1.0
 *
 * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
 *    and "Vovida Open Communication Application Library (VOCAL)" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact [email-masked].
 *
 * 4. Products derived from this software may not be called "VOCAL", nor 
 *    may "VOCAL" appear in their name, without prior written
 *    permission of Vovida Networks, Inc.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
 * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * ====================================================================
 *
 * This software consists of voluntary contributions made by Vovida
 * Networks, Inc. and many individuals on behalf of Vovida Networks,
 * Inc.  For more information on Vovida Networks, Inc., please see
 * <http://www.vovida.org/>.
 *
 */

//static const char* const phoneJack_cxx_Version =
//    "$Id: soundcardTest.cxx,v 1.1 2001/03/09 01:40:55 kimle Exp $";
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/soundcard.h>

//#include "RtpSession.hxx"
//#include "cpLog.h"

#define NETWORK_RTP_RATE 160

static int deviceFD;
//RtpSession* audioStack;
//RtpPacket* outRtpPkt;
//RtpPacket* inRtpPkt;

//RtpPayloadType apiCodec;
static int apiRate;
audio_buf_info info;
void *iPtr,*oPtr;

int openAudioHardware( const char* pname ,int samplingRate)
{
    //cerr <<"Opening audio hardware\n";

    int audioFD,min_size,blk_size=1024,cond,i,p;
    int ioctlParam;

    // open audio device
    if( ( audioFD = open( pname, O_RDWR, 0 ) ) == -1 )
    {
        perror("Open failed:");
        return -1;
    }
#if 0
	ioctl(audioFD,SNDCTL_DSP_GETBLKSIZE,&min_size);
	if(min_size > blk_size)
	{
		cond=1;
		p=min_size/blk_size;
		while(cond)
		{
			i=ioctl(audioFD,SNDCTL_DSP_SUBDIVIDE,&p);
			if((i==0)||(p==1)) cond=0;
			else p=p/2;
		}
	}
	ioctl(audioFD,SNDCTL_DSP_GETBLKSIZE,&min_size);
	printf("SNDCTL_DSP_GETBLKSIZE(size)=%d\n",min_size);
#endif	
    // query audio formats
    ioctlParam = 16;
    if( ioctl( audioFD, SNDCTL_DSP_SAMPLESIZE, &ioctlParam ) == -1 )
    {
        perror("SNDCTL_DSP_SAMPLESIZE");
        return -1;
    }
    ioctlParam = -1;
    if( ioctl( audioFD, SNDCTL_DSP_GETFMTS, &ioctlParam ) == -1 )
    {
        perror("SNDCTL_DSP_GETFMTS");
        return -1;
    }

    // choose codec
    if( ioctlParam & AFMT_MU_LAW )
    {
        //cpLog(LOG_DEBUG,"Setting sound card to ulaw");
        ioctlParam = AFMT_MU_LAW;
        //apiCodec = rtpPayloadPCMU;
        //apiRate = 160;
    }
    else if( ioctlParam & AFMT_S16_LE )
    {
        //cpLog(LOG_DEBUG,"Setting sound card to linear16");
        ioctlParam = AFMT_S16_LE;
        //apiCodec = rtpPayloadL16_mono;
        //apiRate = 320;
    }
    else
    {
        //cpLog(LOG_ERR,"Sound card doesn't support any known encodings");
        printf("Sound card supports the following (Mask:%d:)\n", ioctlParam);
        if( ioctlParam & AFMT_MU_LAW )     printf("  AFMT_MU_LAW\n");
        if( ioctlParam & AFMT_A_LAW )      printf("  AFMT_A_LAW\n");
        if( ioctlParam & AFMT_IMA_ADPCM )  printf("  AFMT_IMA_ADPCM\n");
        if( ioctlParam & AFMT_U8 )         printf("  AFMT_U8\n");
        if( ioctlParam & AFMT_S16_LE )     printf("  AFMT_S16_LE\n");
        if( ioctlParam & AFMT_S16_BE )     printf("  AFMT_S16_BE\n");
        if( ioctlParam & AFMT_S8 )         printf("  AFMT_S8\n");
        if( ioctlParam & AFMT_U16_LE )     printf("  AFMT_U16_LE\n");
        if( ioctlParam & AFMT_U16_BE )     printf("  AFMT_U16_BE\n");
        if( ioctlParam & AFMT_MPEG )       printf("  AFMT_MPEG\n");
        return -1;
    }
    //Setting Duplex
    if( ioctl( audioFD, SNDCTL_DSP_SETDUPLEX,0 ) == -1 )
    {
        perror("SNDCTL_DSP_SETDUPLEX");
        return -1;
    }
    
    // setting audio device parameters
    int ioctlParamSave = ioctlParam;
    if( ioctl( audioFD, SNDCTL_DSP_SETFMT, &ioctlParam ) == -1 )
    {
        perror("SNDCTL_DSP_SETFMT");
        return -1;
    }
    if( ioctlParam != ioctlParamSave )
    {
        perror("Failed to set DSP Format, sound card returned format");
        return -1;
    }
    ioctlParam = 1;
    if( ioctl( audioFD, SNDCTL_DSP_CHANNELS, &ioctlParam ) == -1 )
    {
        perror("SNDCTL_DSP_CHANNELS");
        return -1;
    }
    if( ioctlParam != 1)
    {
        perror("Failed to set channels");
        return -1;
    }

    ioctlParam = samplingRate;
    if( ioctl( audioFD, SNDCTL_DSP_SPEED, &ioctlParam ) == -1 )
    {
        perror("SNDCTL_DSP_SPEED");
        return -1;
    }
    if( ioctlParam != samplingRate )
    {
        perror("Failed to set sample rate");
        return -1;
    }
#if 0
    ioctl(audioFD,SNDCTL_DSP_GETISPACE,&info);
    printf("ISpace\nNo of Fragments:%d,\nTotal fragments allocated for buffering:%d,\nFragment size:%d,\nTotal Available Bytes %d \n\n",info.fragments,info.fragstotal,info.fragsize,info.bytes);
    ioctl(audioFD,SNDCTL_DSP_GETOSPACE,&info);
    printf("OSpace\nNo of Fragments:%d,\nTotal fragments allocated for buffering:%d,\nFragment size:%d,\nTotal Available Bytes %d \n\n",info.fragments,info.fragstotal,info.fragsize,info.bytes);

    //ioctl(audioFD,SNDCTL_DSP_GETOPTR,oPtr);
    //ioctl(audioFD,SNDCTL_DSP_GETOPTR,iPtr);
#endif

    return audioFD;
}

int closeAudioHardware( int audioFD )
{
    //cerr <<"Closing audio hardware\n";

    if( ioctl( audioFD, SNDCTL_DSP_RESET, 0 ) == -1 )
    {
        perror("SNDCTL_DSP_RESET");
    }

    close( audioFD );

    return 1;
}

_______________________________________________
Audio/Video Transport Working Group
[email-masked]
https://www1.ietf.org/mailman/listinfo/avt

---

From: "Fan, Chen (Chen)" <[email-masked]>
Date: Tue, 19 Oct 2004 13:21:21 +0800

Lavin,

Maybe you should try to use separate threads to handle send and receive.

regards
Chen

-----Original Message-----
From: [email-masked] [mailto:[email-masked]]On Behalf Of P Lavin
Sent: Friday, October 15, 2004 4:24 PM
To: Stephen Casner
Cc: [email-masked]
Subject: [AVT] RTP SEND-RECV / Problem with linux 8.0 Sound.

Hi Steve,

while(1)
{
   //read from /dev/dsp.

The problem lies here...

Thanks in Advance,
Regards,
P Lavin