コード例 #1
0
ファイル: iaxvoiplink.cpp プロジェクト: dyfet/sflphone
void
IAXVoIPLink::sendAudioFromMic()
{
    for (CallMap::const_iterator iter = callMap_.begin(); iter != callMap_.end() ; ++iter) {
        IAXCall *currentCall = dynamic_cast<IAXCall*>(iter->second);

        if (!currentCall or currentCall->getState() != Call::ACTIVE)
            continue;

        int codecType = currentCall->getAudioCodec();
        sfl::AudioCodec *audioCodec = static_cast<sfl::AudioCodec *>(Manager::instance().audioCodecFactory.getCodec(codecType));

        if (!audioCodec)
            continue;

        Manager::instance().getMainBuffer()->setInternalSamplingRate(audioCodec->getClockRate());

        unsigned int mainBufferSampleRate = Manager::instance().getMainBuffer()->getInternalSamplingRate();

        // we have to get 20ms of data from the mic *20/1000 = /50
        // rate/50 shall be lower than IAX__20S_48KHZ_MAX
        int bytesNeeded = mainBufferSampleRate * 20 / 1000 * sizeof(SFLDataFormat);

        if (Manager::instance().getMainBuffer()->availForGet(currentCall->getCallId()) < bytesNeeded)
            continue;

        // Get bytes from micRingBuffer to data_from_mic
        int bytes = Manager::instance().getMainBuffer()->getData(decData_, bytesNeeded, currentCall->getCallId());
        int samples = bytes / sizeof(SFLDataFormat);

        int compSize;
        unsigned int audioRate = audioCodec->getClockRate();
        int outSamples;
        SFLDataFormat *in;

        if (audioRate != mainBufferSampleRate) {
            converter_.resample(decData_, resampledData_, ARRAYSIZE(resampledData_),
                                audioRate, mainBufferSampleRate, samples);
            in = resampledData_;
            outSamples = 0;
        } else {
            outSamples = samples;
            in = decData_;
        }

        compSize = audioCodec->encode(encodedData_, in, DEC_BUFFER_SIZE);

        if (currentCall->session and bytes > 0) {
            ost::MutexLock m(mutexIAX_);

            if (iax_send_voice(currentCall->session, currentCall->format, encodedData_, compSize, outSamples) == -1)
                ERROR("IAX: Error sending voice data.");
        }
    }
}
コード例 #2
0
ファイル: iaxclient_lib.c プロジェクト: dochong/iaxclient
EXPORT int iaxc_push_audio(void *data, unsigned int size, unsigned int samples)
{
	struct iaxc_call *call;

	if ( selected_call < 0 )
		return -1;

	call = &calls[selected_call];

	if ( audio_prefs & IAXC_AUDIO_PREF_SEND_DISABLE )
		return 0;

	//fprintf(stderr, "iaxc_push_audio: sending audio size %d\n", size);

	if ( iax_send_voice(call->session, call->format, data, size, samples) == -1 )
	{
		fprintf(stderr, "iaxc_push_audio: failed to send audio frame of size %d on call %d\n", size, selected_call);
		return -1;
	}

	return 0;
}
コード例 #3
0
ファイル: audio_encode.c プロジェクト: Affix/fgcom
int send_encoded_audio(struct iaxc_call *call, void *data, int format, int samples)
{
	unsigned char outbuf[1024];
	int outsize = 1024;
	int silent;
	int insize = samples;

	//fprintf(stderr, "in encode_audio, format=%d\n", format);

	/* update last input timestamp */
	gettimeofday( &timeLastInput, NULL ) ;

	silent = iaxc_input_postprocess(data,insize,8000);	

	if(silent) { 
	  if(!call->tx_silent) {  /* send a Comfort Noise Frame */
	    call->tx_silent = 1;
	    if(iaxc_filters & IAXC_FILTER_CN)
		iax_send_cng(call->session, 10, NULL, 0);
	  }
	  return 0;  /* poof! no encoding! */
	}

	/* we're going to send voice now */
	call->tx_silent = 0;

	/* destroy encoder if it is incorrect type */
	if(call->encoder && call->encoder->format != format)
	{
	    call->encoder->destroy(call->encoder);
	    call->encoder = NULL;
	}

	/* just break early if there's no format defined: this happens for the
	 * first couple of frames of new calls */
	if(format == 0)
	  return 0;

	/* create encoder if necessary */
	if(!call->encoder) {
	    call->encoder = create_codec(format);
	}

	if(!call->encoder) {
		  /* ERROR: no codec */
		  fprintf(stderr, "ERROR: Codec could not be created: %d\n", format);
		  return 0;
	}

	if(call->encoder->encode(call->encoder, &insize, (short *)data, &outsize, outbuf)) {
		  /* ERROR: codec error */
		  fprintf(stderr, "ERROR: encode error: %d\n", format);
		  return 0;
	}
	
	if(samples-insize == 0)
	{
	    fprintf(stderr, "ERROR encoding (no samples output (samples=%d)\n", samples);
	    return -1;
	}

	if(iax_send_voice(call->session,format, outbuf, 1024-outsize, samples-insize) == -1) 
	{
	      puts("Failed to send voice!");
	      return -1;
	}
	
	return 0;
}
コード例 #4
0
ファイル: audio_encode.c プロジェクト: ACSPRI/iaxclient-1
int audio_send_encoded_audio(struct iaxc_call *call, int callNo, void *data,
		int format, int samples)
{
	unsigned char outbuf[1024];
	int outsize = 1024;
	int silent;
	int insize = samples;

	/* update last input timestamp */
	timeLastInput = iax_tvnow();

	silent = input_postprocess(data, insize, 8000);

	if(silent)
	{
		if(!call->tx_silent)
		{  /* send a Comfort Noise Frame */
			call->tx_silent = 1;
			if ( iaxci_filters & IAXC_FILTER_CN )
				iax_send_cng(call->session, 10, NULL, 0);
		}
		return 0;  /* poof! no encoding! */
	}

	/* we're going to send voice now */
	call->tx_silent = 0;

	/* destroy encoder if it is incorrect type */
	if(call->encoder && call->encoder->format != format)
	{
		call->encoder->destroy(call->encoder);
		call->encoder = NULL;
	}

	/* just break early if there's no format defined: this happens for the
	 * first couple of frames of new calls */
	if(format == 0) return 0;

	/* create encoder if necessary */
	if(!call->encoder)
	{
		call->encoder = create_codec(format);
	}

	if(!call->encoder)
	{
		/* ERROR: no codec */
		fprintf(stderr, "ERROR: Codec could not be created: %d\n", format);
		return 0;
	}

	if(call->encoder->encode(call->encoder, &insize, (short *)data,
				&outsize, outbuf))
	{
		/* ERROR: codec error */
		fprintf(stderr, "ERROR: encode error: %d\n", format);
		return 0;
	}

	if(samples-insize == 0)
	{
		fprintf(stderr, "ERROR encoding (no samples output (samples=%d)\n", samples);
		return -1;
	}

	// Send the encoded audio data back to the app if required
	// TODO: fix the stupid way in which the encoded audio size is returned
	if ( iaxc_get_audio_prefs() & IAXC_AUDIO_PREF_RECV_LOCAL_ENCODED )
		iaxci_do_audio_callback(callNo, 0, IAXC_SOURCE_LOCAL, 1,
				call->encoder->format & IAXC_AUDIO_FORMAT_MASK,
				sizeof(outbuf) - outsize, outbuf);

	if(iax_send_voice(call->session,format, outbuf,
				sizeof(outbuf) - outsize, samples-insize) == -1)
	{
		fprintf(stderr, "Failed to send voice! %s\n", iax_errstr);
		return -1;
	}

	return 0;
}
コード例 #5
0
ファイル: miniphone.c プロジェクト: ThereIsNoYeti/sflphone
int
main(int argc, char *argv[])
{
	int port;
	int netfd;
 	int c, h=0, m, regm;
	FILE *f;
	int fd = STDIN_FILENO;
	char rcmd[RBUFSIZE];
	fd_set readfd;
	fd_set writefd;
	struct timeval timer;
	struct timeval *timerptr = NULL;
	gsm_frame fo;

	load_options();

	if (!strlen(callerid))
		gethostname(callerid, sizeof(callerid));

	signal(SIGHUP, sighandler);
	signal(SIGINT, sighandler);

	if ( !(f = fdopen(fd, "w+"))) {
		fprintf(stderr, "Unable to create file on fd %d\n", fd);
		return -1;
	}

	if ( (audiofd = audio_setup(audiodev)) == -1) {
		fprintf(stderr, "Fatal error: failed to open sound device");
		return -1;
	}

	if ( (port = iax_init(0) < 0)) {
		fprintf(stderr, "Fatal error: failed to initialize iax with port %d\n", port);
		return -1;
	}

	iax_set_formats(AST_FORMAT_GSM);
	netfd = iax_get_fd();

	check_iax_register();

	fprintf(f, "Text Based Telephony Client.\n\n");
	issue_prompt(f);

	timer.tv_sec = 0;
	timer.tv_usec = 0;

	while(1) {
		FD_ZERO(&readfd);
		FD_ZERO(&writefd);
		FD_SET(fd, &readfd);
			if(fd > h)
				h = fd;
		if(answered_call && !writeonly) {
			FD_SET(audiofd, &readfd);
				if(audiofd > h)
					h = audiofd;
		}
		if (cursound > -1) {
			FD_SET(audiofd, &writefd);
			if (audiofd > h)
				h = audiofd;
		}
		FD_SET(netfd, &readfd);
		if(netfd > h)
			h = netfd;

		if ( (c = select(h+1, &readfd, &writefd, 0, timerptr)) >= 0) {
			if(FD_ISSET(fd, &readfd)) {
				if ( ( fgets(&*rcmd, 256, f))) {
					rcmd[strlen(rcmd)-1] = 0;
					parse_args(f, &*rcmd);
				} else fprintf(f, "Fatal error: failed to read data!\n");

				issue_prompt(f);
			}
			if(answered_call) {
				if(FD_ISSET(audiofd, &readfd)) {
				static int ret, rlen = 0;
					static short rbuf[FRAME_SIZE];

					if ( (ret = read(audiofd, rbuf + rlen, 2 * (FRAME_SIZE-rlen))) == -1) {
						puts("Failed to read audio.");
						return -1;
					}
					rlen += ret/2;
					if(rlen == FRAME_SIZE) {
						rlen = 0;

						if(!most_recent_answer->gsmout)
							most_recent_answer->gsmout = gsm_create();

						gsm_encode(most_recent_answer->gsmout, rbuf, fo);
						if(iax_send_voice(most_recent_answer->session,
						AST_FORMAT_GSM, (char *)fo, sizeof(fo)) == -1)
							puts("Failed to send voice!");
					}
				}
			}
			do_iax_event(f);
			m = iax_time_to_next_event();
			if(m > -1) {
				timerptr = &timer;
				timer.tv_sec = m /1000;
				timer.tv_usec = (m % 1000) * 1000;
			} else
				timerptr = 0;
			regm = check_iax_timeout();
			if (!timerptr || (m > regm)) {
				timerptr = &timer;
				timer.tv_sec = regm /1000;
				timer.tv_usec = (regm % 1000) * 1000;
			}
			if (FD_ISSET(audiofd, &writefd)) {
				send_sound(audiofd);
			}
		} else {
			if(errno == EINTR)
				continue;
			fprintf(stderr, "Fatal error in select(): %s\n", strerror(errno));
			return -1;
		}
	}
	return 0;
}