Exemple #1
0
/* TODO: Move UDP socket creation to connection handler thread
 * Faced a bug when capture thread executed before send_audio
 * thread had established UDP socket and as a result, server
 * lost AUDIO_RQST from client 
 */
int send_audio(struct connection_data *_conn)
{
    /* send data over the UDP socket */
	struct connection_data conn = *_conn;
	int sockfd = conn.udp_sock_rx;
	struct sockaddr_in other, own;
	short audio_samples[SPEEX_FRAME_SIZE];
	char buffer[512];
	char compressed[SPEEX_FRAME_SIZE];
	int addrlen;
	int rc;
	int i;

	/* variables for speex */
        SpeexBits bits;
        void *state; /* For holding encoder state */
        int quality;
	int nbytes, count;

        dbg("Preparing speex for compression");

        state = speex_encoder_init(&speex_nb_mode);
        /* Set the quality to 8 (15 kbps) */
        quality = 8;
        speex_encoder_ctl(state, SPEEX_SET_QUALITY, &quality);

        speex_bits_init(&bits);
	
	dbg("Preparing to send audio over UDP socket");

	own = conn.own;
	other = conn.other;
	other.sin_port = htons(8889);

	addrlen = sizeof other;
		
		/* send data here */
		/* TODO: How to end the send? */
		//dbg("Sending audio data to other side \n");
		memset(compressed, 0, sizeof compressed);
		memset(buffer, 0, sizeof buffer);
                printf("Trying data send\n");
		/* Instead of multiple sends over socket, compress the complete audio buffer size
		 * of data, each encoding results in 38 bytes, so a 512 bytes transmit buffer
		 * can accomodate over 512 / 38 ~ 13 160 bytes speex frames. We are sending only
		 * 5 (i.e 800 / 160) speex frames for our audio buffer of 800 frames */
		for (i = 0, count = 0; i < 5; i++) {
                	/* if read is unsuccessful, wait for capture thread
                 	* to write audio data to sbuff */
                	rc = ring_read(sbuff, (char *)audio_samples, sizeof audio_samples);
			printf("Read %d bytes from tx circular buffer \n", rc);	
			speex_bits_reset(&bits);
			/* Encode here */
			speex_encode_int(state, audio_samples, &bits);
			/* Write the encoded bits to array of bytes so that they can be written */
			nbytes = speex_bits_write(&bits, compressed, sizeof compressed);

			memcpy(buffer + i * 38, compressed, nbytes);
			count += nbytes;
			//printf("Size of compressed data: %d \n", nbytes);
			//printf("Size of audio_samples: %d \n", sizeof audio_samples);
			//printf("Iteration no : %d \n", i + 1);
		}
		
		if ((rc =sendto(sockfd, buffer, sizeof buffer, 0, (struct sockaddr *)&other, addrlen)) < 0) {
			fprintf(stderr,
		        	"Unable to send data to other side \n");
		} else 
                	printf("Data sent: %d bytes\n", rc);
		
	
	dbg("Freeing up speex resources");
	/* Destroy the encoder state */
        speex_encoder_destroy(state);
        /* Destroy the bits-packing */
        speex_bits_destroy(&bits);
	
#if 0	
send_sock_close:
	dbg("Closing UDP socket connection");
	/* stop reception and transmission */
        if (rc = shutdown(sockfd, 2)) {
                fprintf(stderr,
                        "Unable to end connection: %s \n",
                        strerror(errno));
        }
        /* close the socket so that it can be reused */
        close(sockfd);
	
audio_end:
	 
        pthread_exit(NULL);
#endif
}
Exemple #2
0
void *receive_audio(void *data)
{
	struct connection_data conn = *((struct connection_data *)data);	
	struct sockaddr_in other = conn.other; 
	char buffer[512];
	char compressed[SPEEX_FRAME_SIZE];
	short audio_samples[SPEEX_FRAME_SIZE];	
	int sockfd = conn.udp_sock_rx; /* Descriptor for UDP socket */
	/* receive data from socket, add to buffer */
	int addrlen = sizeof other;
	int rc;
	/* variables for speex */
        SpeexBits bits;
        void *state; /* For holding encoder state */
        int tmp;
	int nbytes;
	int i;

	int ret;
        unsigned int rate = 8000;
        int size;
        short playback_samples[SAMPLES_PER_PERIOD];
        int fd;
        int frame_size = 2;

	snd_pcm_t *handle;
        snd_pcm_hw_params_t *params;
        /* write many data at a time to device */
        /* the value of 5512 comes from aplay, investigate
         * why it is so */
	int buffer_size = SAMPLES_PER_PERIOD * sizeof(short);

        printf("rate is =%d \n", rate);

	dbg("Preparing audio playback");
        ret = voip_init_pcm(&handle, &params, &buffer_size, &rate, PLAYBACK);
        
	if (ret < 0) {
		fprintf(stderr,
			"Failed to prepare audio system\n");
		goto rcv_audio_end;
	}

	printf("Pointer address to handle=%p \n", &handle);
        printf("Pointer to handle=%p \n", handle);
        printf("Pointer to params=%p \n", params);
	
	dbg("Preparing speex for de-compression");
        state = speex_decoder_init(&speex_nb_mode);
	tmp = 1;
        speex_decoder_ctl(state, SPEEX_SET_ENH, &tmp);
        speex_bits_init(&bits);

	while(1) {
		memset(audio_samples, 0, sizeof audio_samples);
		memset(compressed, 0, sizeof compressed);
		memset(buffer, 0, sizeof buffer);
		printf("Waiting for data\n");
		if ((rc = recvfrom(sockfd, buffer, sizeof buffer, 0,
				(struct sockaddr *)&other, &addrlen)) < 0) {
			fprintf(stderr,
				"Unable to receive audio data: %s \n",
				strerror(errno));
			goto rcv_sock_close;
		}
		printf("Received %d compressed bytes on UDP socket \n", rc);

		for (i = 0; i < 5; i++) {
			speex_bits_reset(&bits);
			/* each encoded speex frame takes 38 bytes */
			memcpy(compressed, buffer + i * 38, 38);

                	speex_bits_read_from(&bits, compressed, 38);
		
			/* Decode here */
                	speex_decode_int(state, &bits, audio_samples);	
		
			ring_write(rbuff, (char *)audio_samples, sizeof audio_samples);

		}
		ret = ring_read(rbuff, (char *)audio_samples, buffer_size);
		if ( ret != buffer_size) {
                        fprintf(stderr,
                                "short read: read %d bytes \n", ret);
                }
                printf("Playing audio \n");
                /* write frames in one period to device */
                ret = voip_playback(handle, buffer_size / frame_size, audio_samples);
	}

        voip_end_pcm(handle);
	/* Destroy the encoder state */
        speex_decoder_destroy(state);
        /* Destroy the bits-packing */
        speex_bits_destroy(&bits);

rcv_sock_close:
	close(sockfd);	

rcv_audio_end:
        pthread_exit(NULL);
}
Exemple #3
0
int main(int argc, char **argv) {
    if (argc == 1) {
        signal(SIGCHLD, SIG_IGN);
        int pid = remote_spawn(argv[0]);
        if (pid < 1) {
            fprintf(stderr, "failed to spawn remote\n");
            return 1;
        }
        state.remote = 1;
        for (int i = 0; i < RACE_COUNT; i++) {
            glRectf(0, 0, 1, 1);
        }
        int status = 0;
        waitpid(pid, &status, 0);
        if (WEXITSTATUS(status) || WTERMSIG(status)) {
            fprintf(stderr, "Error from libgl_remote: %d\n", status);
            return 1;
        }
    } else {
        ring_t _ring = {0};
        ring_t *ring = &_ring;
        ring_setup(ring, strtol(argv[1]+1, NULL, 10));
        if (ring_server_handshake(ring)) {
            fprintf(stderr, "Error doing server handshake\n");
            return 2;
        }
        for (int i = 0; i < RACE_COUNT - 1; i++) {
            // fprintf(stderr, "remote %d\n", i);
            // fprintf(stderr, "reading retsize\n");
            void *buf = ring_read(ring, NULL);
            uint32_t retsize = *(uint32_t *)buf;
            // fprintf(stderr, "retsize=%d\n", retsize);
            if (retsize != 0) {
                unsigned char *c = buf;
                fprintf(stderr, "ERROR: Expected retsize=0. Got: %d\n", retsize);
                fprintf(stderr, "read=%d, mark=%d, call=%d, write=%d, %02X%02X %02X%02X %02x%02x %02x%02x\n", *ring->read, *ring->mark, (uintptr_t)c - (uintptr_t)ring->buf, *ring->write, c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]);
                kill(getppid(), SIGTERM);
                return 1;
            }
            // fprintf(stderr, "reading call\n");
            packed_call_t *call = buf + sizeof(uint32_t);
            unsigned char *c = call;
            // fprintf(stderr, "read=%d, mark=%d, call=%d, write=%d, %02X%02X %02X%02X %02x%02x %02x%02x %d\n", *ring->read, *ring->mark, (uintptr_t)c - (uintptr_t)ring->buf, *ring->write, c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], call->index);

            if (call->index != REMOTE_BLOCK_DRAW) {
                fprintf(stderr, "ERROR: Expected REMOTE_BLOCK_DRAW. Got: %d\n", call->index);
                fprintf(stderr, "read=%d, mark=%d, call=%d, write=%d, %02X%02X %02X%02X %02x%02x %02x%02x %d\n", *ring->read, *ring->mark, (uintptr_t)c - (uintptr_t)ring->buf, *ring->write, c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], call->index);
                kill(getppid(), SIGTERM);
                return 1;
            }
            block_t *block = remote_read_block(ring, (void *)call);
            // fprintf(stderr, "block->len: %d\n", block->len);
            if (block->len != 4) {
                fprintf(stderr, "ERROR: Expected block->len == 4, got: %d\n", block->len);
                fprintf(stderr, "read=%d, mark=%d, call=%d, write=%d, %02X%02X %02X%02X %02x%02x %02x%02x %d\n", *ring->read, *ring->mark, (uintptr_t)c - (uintptr_t)ring->buf, *ring->write, c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], call->index);
                kill(getppid(), SIGTERM);
                return 1;
            }
            ring_advance(ring);
        }
    }
    return 0;
}
Exemple #4
0
void ring_read_into(ring_t *ring, void *dst) {
    size_t size;
    void *data = ring_read(ring, &size);
    memcpy(dst, data, size);
}
static int tcpclient_buffer_read(urg_tcpclient_t* cli, char* data, int size)
{
    return ring_read(&cli->rb, data, size);
}
Exemple #6
0
static void writeout_ext(multiplex_t *mx, int n)
{  
	uint8_t outbuf[3000];
	int written=0;
	unsigned int length=0;
	int nlength=0;
	uint64_t pts, dpts=0;
	int newpts=0;
	int nframes=1;
	int ac3_off=0;
	int rest_data = 5;

	int type = mx->ext[n].type;
	ringbuffer *airbuffer = &mx->index_extrbuffer[n];
	dummy_buffer *dbuf = &mx->ext[n].dbuf;
	uint64_t adelay = mx->ext[n].pts_off;
	uint64_t *apts = &mx->ext[n].pts;
	index_unit *aiu = &mx->ext[n].iu;

	switch (type){

	case MPEG_AUDIO:
#ifdef OUT_DEBUG
		fprintf(stderr,"writing AUDIO%d pack\n",n);
#endif
		break;

	case AC3:
#ifdef OUT_DEBUG
		fprintf(stderr,"writing AC3%d pack\n",n);
#endif
		rest_data = 1; // 4 bytes AC3 header
		break;

	default:
		return;
	}
	
	if (mx->finish != 2 && dummy_space(dbuf) < mx->data_size + rest_data){
		return;
	}

	pts = uptsdiff( aiu->pts + mx->audio_delay, adelay );
	*apts = pts;
	length = aiu->length;
	if (length < aiu->framesize){
		newpts = 1;
		ac3_off = length;
	}
	dummy_add(dbuf, pts, aiu->length);

#ifdef OUT_DEBUG
	fprintf(stderr,"start: %d  stop: %d (%d)  length %d ", 
		aiu->start, (aiu->start+aiu->length),
		aiu->length, length);
	printpts(*apts);
	printpts(aiu->pts);
	printpts(mx->audio_delay);
	printpts(adelay);
	printpts(pts);
	fprintf(stderr,"\n");
#endif
	while (!mx->is_ts && length  < mx->data_size + rest_data){
		if (ring_read(airbuffer, (uint8_t *)aiu, sizeof(index_unit)) > 0){
			dpts = uptsdiff(aiu->pts +mx->audio_delay, adelay );
			
			if (newpts){
				pts = dpts;
				newpts=0;
			}

			length+= aiu->length;
			if (length < mx->data_size + rest_data)
				dummy_add(dbuf, dpts, aiu->length);
			
			*apts = dpts;
			nframes++;
#ifdef OUT_DEBUG
			fprintf(stderr,"start: %d  stop: %d (%d)  length %d ", 
				aiu->start, (aiu->start+aiu->length),
				aiu->length, length);
			printpts(*apts);
			printpts(aiu->pts);
			printpts(mx->audio_delay);
			printpts(adelay);
			fprintf(stderr,"\n");
#endif
		} else if (mx->finish){
			break;
		} else if (mx->fill_buffers(mx->priv, mx->finish)< 0) {
			fprintf(stderr,"error in writeout ext\n");
			exit(1);
		}
	}

	nlength = length;

	switch (type) {
	case MPEG_AUDIO:
		if(mx->is_ts)
			written = write_audio_ts( mx->ext[n].strmnum, pts,
					outbuf, &nlength, newpts ? 0 : PTS_ONLY,
					&mx->extrbuffer[n]);
		else
			written = write_audio_pes( mx->pack_size, mx->extcnt,
					mx->ext[n].strmnum, pts, mx->SCR,
					mx->muxr, outbuf, &nlength, PTS_ONLY,
					&mx->extrbuffer[n]);
		break;
	case AC3:
		if(mx->is_ts)
			written = write_ac3_ts(mx->ext[n].strmnum, pts,
					outbuf, &nlength, newpts ? 0 : PTS_ONLY,
					mx->ext[n].frmperpkt, &mx->extrbuffer[n]);
		else
			written = write_ac3_pes( mx->pack_size, mx->extcnt,
					mx->ext[n].strmnum, pts, mx->SCR,
					mx->muxr, outbuf, &nlength, PTS_ONLY,
					nframes, ac3_off,
					&mx->extrbuffer[n]);
		break;
	}

	length -= nlength;
	write(mx->fd_out, outbuf, written);

	dummy_add(dbuf, dpts, aiu->length-length);
	aiu->length = length;
	aiu->start = ring_rpos(&mx->extrbuffer[n]);

	if (aiu->length == 0){
		get_next_ext_unit(mx, aiu, n);
	} else {
		//estimate next pts based on bitrate of stream and data written
		aiu->pts = uptsdiff(aiu->pts + ((nlength*aiu->ptsrate)>>8), 0);
	}
	*apts = uptsdiff(aiu->pts + mx->audio_delay, adelay);
#ifdef OUT_DEBUG
	if ((int64_t)*apts < 0) fprintf(stderr,"SCHEISS ");
	fprintf(stderr,"APTS");
	printpts(*apts);
	printpts(aiu->pts);
	printpts(mx->audio_delay);
	printpts(adelay);
	fprintf(stderr,"\n");
#endif

	if (mx->fill_buffers(mx->priv, mx->finish)< 0) {
		fprintf(stderr,"error in writeout ext\n");
		exit(1);
	}
}