Exemplo n.º 1
0
size_t WebRtcG711_EncodeU(const int16_t* speechIn,
                          size_t len,
                          uint8_t* encoded) {
  size_t n;
  for (n = 0; n < len; n++)
    encoded[n] = linear_to_ulaw(speechIn[n]);
  return len;
}
Exemplo n.º 2
0
static apt_bool_t g711u_init(mpf_codec_t *codec, mpf_codec_frame_t *frame_out)
{
	apr_size_t i;
	unsigned char *encode_buf = frame_out->buffer;
	for(i=0; i<frame_out->size; i++) {
		encode_buf[i] = linear_to_ulaw(0);
	}

	return TRUE;
}
Exemplo n.º 3
0
static apt_bool_t g711u_encode(mpf_codec_t *codec, const mpf_codec_frame_t *frame_in, mpf_codec_frame_t *frame_out)
{
	const apr_int16_t *decode_buf;
	unsigned char *encode_buf;
	apr_size_t i;

	decode_buf = frame_in->buffer;
	encode_buf = frame_out->buffer;

	frame_out->size = frame_in->size / sizeof(apr_int16_t);

	for(i=0; i<frame_out->size; i++) {
		encode_buf[i] = linear_to_ulaw(decode_buf[i]);
	}

	return TRUE;
}
Exemplo n.º 4
0
SPAN_DECLARE(void) codec_munge(codec_munge_state_t *s, int16_t amp[], int len)
{
    uint8_t law;
    uint8_t adpcmdata[160];
    int i;
    int adpcm;
    int x;

    switch (s->munging_codec)
    {
    case MUNGE_CODEC_NONE:
        /* Do nothing */
        break;
    case MUNGE_CODEC_ALAW:
        for (i = 0;  i < len;  i++)
        {
            law = linear_to_alaw(amp[i]);
            amp[i] = alaw_to_linear(law);
        }
        break;
    case MUNGE_CODEC_ULAW:
        for (i = 0;  i < len;  i++)
        {
            law = linear_to_ulaw(amp[i]);
            if (s->rbs_pattern & (1 << s->sequence))
            {
                /* Strip the bottom bit at the RBS rate */
                law &= 0xFE;
            }
            amp[i] = ulaw_to_linear(law);
        }
        break;
    case MUNGE_CODEC_G726_32K:
        /* This could actually be any of the G.726 rates */
        for (i = 0;  i < len;  i += x)
        {
            x = (len - i >= 160)  ?  160  :  (len - i);
            adpcm = g726_encode(&s->g726_enc_state, adpcmdata, amp + i, x);
            g726_decode(&s->g726_dec_state, amp + i, adpcmdata, adpcm);
        }
        break;
    }
}
Exemplo n.º 5
0
static switch_status_t switch_g711u_encode(switch_codec_t *codec,
										   switch_codec_t *other_codec,
										   void *decoded_data,
										   uint32_t decoded_data_len,
										   uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate,
										   unsigned int *flag)
{
	short *dbuf;
	unsigned char *ebuf;
	uint32_t i;

	dbuf = decoded_data;
	ebuf = encoded_data;

	for (i = 0; i < decoded_data_len / sizeof(short); i++) {
		ebuf[i] = linear_to_ulaw(dbuf[i]);
	}

	*encoded_data_len = i;

	return SWITCH_STATUS_SUCCESS;
}
Exemplo n.º 6
0
int g711_encode(g711_state_t *s,
                uint8_t g711_data[],
                const int16_t amp[],
                int len)
{
    int i;

    if (s->mode == G711_ALAW)
    {
        for (i = 0;  i < len;  i++)
            g711_data[i] = linear_to_alaw(amp[i]);
        /*endfor*/
    }
    else
    {
        for (i = 0;  i < len;  i++)
            g711_data[i] = linear_to_ulaw(amp[i]);
        /*endfor*/
    }
    /*endif*/
    return len;
}
Exemplo n.º 7
0
void codec_munge(codec_munge_state_t *s, int16_t amp[], int len)
{
    uint8_t law;
    uint8_t adpcmdata[160];
    int i;
    int adpcm;
    int x;

    switch (s->munging_codec)
    {
    case MUNGE_CODEC_NONE:
        /* Do nothing */
        break;
    case MUNGE_CODEC_ALAW:
        for (i = 0;  i < len;  i++)
        {
            law = linear_to_alaw(amp[i]);
            amp[i] = alaw_to_linear(law);
        }
        break;
    case MUNGE_CODEC_ULAW:
        for (i = 0;  i < len;  i++)
        {
            law = linear_to_ulaw(amp[i]);
            amp[i] = ulaw_to_linear(law);
        }
        break;
    case MUNGE_CODEC_G726_32K:
        /* This could actually be any of the G.726 rates */
        for (i = 0;  i < len;  i += x)
        {
            x = (len - i >= 160)  ?  160  :  (len - i);
            adpcm = g726_encode(&s->g726_enc_state, adpcmdata, amp + i, x);
            g726_decode(&s->g726_dec_state, amp + i, adpcmdata, adpcm);
        }
        break;
    }
}
static int perform_law_test(int full, int law, const char *name)
{
    gsm0610_state_t *gsm0610_enc_state;
    gsm0610_state_t *gsm0610_dec_state;
    int i;
    int xxx;
    int mismatches;

    if (law == 'a')
        printf("Performing A-law test '%s'\n", name);
    else
        printf("Performing u-law test '%s'\n", name);
        
    get_law_test_vector(full, law, name);

    if (full)
    {
        if ((gsm0610_enc_state = gsm0610_init(NULL, GSM0610_PACKING_NONE)) == NULL)
        {
            fprintf(stderr, "    Cannot create encoder\n");
            exit(2);
        }
        if (law == 'a')
        {
            for (i = 0;  i < vector_len;  i++)
                in_vector[i] = alaw_to_linear(law_in_vector[i]);
        }
        else
        {
            for (i = 0;  i < vector_len;  i++)
                in_vector[i] = ulaw_to_linear(law_in_vector[i]);
        }
        xxx = gsm0610_encode(gsm0610_enc_state, code_vector, in_vector, vector_len);

        printf("Check code vector of length %d\n", xxx);
        for (i = 0, mismatches = 0;  i < xxx;  i++)
        {
            if (code_vector[i] != ref_code_vector[i])
            {
                printf("%8d/%3d: %6d %6d %6d\n", i/76, i%76, code_vector[i], ref_code_vector[i], decoder_code_vector[i]);
                mismatches++;
            }
        }
        if (mismatches)
        {
            printf("Test failed: %d of %d samples mismatch\n", mismatches, xxx);
            exit(2);
        }
        printf("Test passed\n");
        gsm0610_release(gsm0610_enc_state);
    }

    if ((gsm0610_dec_state = gsm0610_init(NULL, GSM0610_PACKING_NONE)) == NULL)
    {
        fprintf(stderr, "    Cannot create decoder\n");
        exit(2);
    }
    xxx = gsm0610_decode(gsm0610_dec_state, out_vector, decoder_code_vector, vector_len);
    if (law == 'a')
    {
        for (i = 0;  i < vector_len;  i++)
            law_out_vector[i] = linear_to_alaw(out_vector[i]);
    }
    else
    {
        for (i = 0;  i < vector_len;  i++)
            law_out_vector[i] = linear_to_ulaw(out_vector[i]);
    }
    printf("Check output vector of length %d\n", vector_len);
    for (i = 0, mismatches = 0;  i < vector_len;  i++)
    {
        if (law_out_vector[i] != ref_law_out_vector[i])
        {
            printf("%8d: %6d %6d\n", i, law_out_vector[i], ref_law_out_vector[i]);
            mismatches++;
        }
    }
    if (mismatches)
    {
        printf("Test failed: %d of %d samples mismatch\n", mismatches, vector_len);
        exit(2);
    }
    gsm0610_release(gsm0610_dec_state);
    printf("Test passed\n");
    return 0;
}
Exemplo n.º 9
0
 static uint8_t ULawEncode(SFLAudioSample pcm16) {
     return linear_to_ulaw(pcm16);
 }
Exemplo n.º 10
0
static switch_bool_t oreka_audio_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
{
	oreka_session_t *oreka = user_data;
	switch_core_session_t *session = oreka->session;
	switch_frame_t pcmu_frame = { 0 };
    switch_frame_t *linear_frame, raw_frame = { 0 };
	uint8_t pcmu_data[SWITCH_RECOMMENDED_BUFFER_SIZE];
	uint8_t raw_data[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 };
	uint8_t resample_data[SWITCH_RECOMMENDED_BUFFER_SIZE];
    uint32_t linear_len = 0;
	uint32_t i = 0;
	int16_t *linear_samples = NULL;

    

	if (type == SWITCH_ABC_TYPE_READ_REPLACE || type == SWITCH_ABC_TYPE_WRITE_REPLACE || type == SWITCH_ABC_TYPE_READ_PING) {
        int16_t *data;

        if (type == SWITCH_ABC_TYPE_READ_REPLACE || type == SWITCH_ABC_TYPE_READ_PING) {

            if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
                linear_frame = switch_core_media_bug_get_read_replace_frame(bug);
            } else {
                switch_status_t status;

                raw_frame.data = raw_data;
                raw_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
                linear_frame = &raw_frame;

                status = switch_core_media_bug_read(bug, &raw_frame, SWITCH_FALSE);
                if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
                    return SWITCH_TRUE;
                }
            }

            if (oreka->read_resampler) {
                data = (int16_t *) linear_frame->data;
                switch_resample_process(oreka->read_resampler, data, (int) linear_frame->datalen / 2);
                linear_len = oreka->read_resampler->to_len * 2;
                memcpy(resample_data, oreka->read_resampler->to, linear_len);
                linear_samples = (int16_t *)resample_data;
            } else {
                linear_samples = linear_frame->data;
                linear_len = linear_frame->datalen;
            }
        }

        if (type == SWITCH_ABC_TYPE_WRITE_REPLACE) {
            linear_frame = switch_core_media_bug_get_write_replace_frame(bug);

            if (oreka->write_resampler) {
                data = (int16_t *) linear_frame->data;
                switch_resample_process(oreka->write_resampler, data, (int) linear_frame->datalen / 2);
                linear_len = oreka->write_resampler->to_len * 2;
                memcpy(resample_data, oreka->write_resampler->to, linear_len);
                linear_samples = (int16_t *)resample_data;
            } else {
                linear_samples = linear_frame->data;
                linear_len = linear_frame->datalen;
            }
        }

		/* convert the L16 frame into PCMU */
		memset(&pcmu_frame, 0, sizeof(pcmu_frame));
		for (i = 0; i < linear_len / sizeof(int16_t); i++) {
			pcmu_data[i] = linear_to_ulaw(linear_samples[i]);
		}
		pcmu_frame.source = __FUNCTION__;
		pcmu_frame.data = pcmu_data;
		pcmu_frame.datalen = i;
		pcmu_frame.payload = 0;
	}

	switch (type) {
	case SWITCH_ABC_TYPE_INIT:
		{
            switch_codec_implementation_t read_impl;

            switch_core_session_get_read_impl(session, &read_impl);

            if (read_impl.actual_samples_per_second != 8000) {
                switch_resample_create(&oreka->read_resampler,
                                       read_impl.actual_samples_per_second,
                                       8000,
                                       320, SWITCH_RESAMPLE_QUALITY, 1);

                switch_resample_create(&oreka->write_resampler,
                                       read_impl.actual_samples_per_second,
                                       8000,
                                       320, SWITCH_RESAMPLE_QUALITY, 1);                
            }


			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Starting Oreka recording for audio stream\n");
			oreka_send_sip_message(oreka, FS_OREKA_START, FS_OREKA_READ);
            if (!oreka->mux_streams) {
                oreka_send_sip_message(oreka, FS_OREKA_START, FS_OREKA_WRITE);
            }
		}
		break;
	case SWITCH_ABC_TYPE_CLOSE:
		{
            if (oreka->mux_streams) {
                int16_t *data;

                raw_frame.data = raw_data;
                raw_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
                linear_frame = &raw_frame;

                while (switch_core_media_bug_read(bug, &raw_frame, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
                    linear_frame = &raw_frame;


                    if (oreka->read_resampler) {
                        data = (int16_t *) linear_frame->data;
                        switch_resample_process(oreka->read_resampler, data, (int) linear_frame->datalen / 2);
                        linear_len = oreka->read_resampler->to_len * 2;
                        memcpy(resample_data, oreka->read_resampler->to, linear_len);
                        linear_samples = (int16_t *)resample_data;
                    } else {
                        linear_samples = linear_frame->data;
                        linear_len = linear_frame->datalen;
                    }
                    
                    memset(&pcmu_frame, 0, sizeof(pcmu_frame));
                    for (i = 0; i < linear_len / sizeof(int16_t); i++) {
                        pcmu_data[i] = linear_to_ulaw(linear_samples[i]);
                    }
                    pcmu_frame.source = __FUNCTION__;
                    pcmu_frame.data = pcmu_data;
                    pcmu_frame.datalen = i;
                    pcmu_frame.payload = 0;

                    switch_rtp_write_frame(oreka->read_rtp_stream, &pcmu_frame);
                }
            }


            if (oreka->read_resampler) {
                switch_resample_destroy(&oreka->read_resampler);
            }

            if (oreka->write_resampler) {
                switch_resample_destroy(&oreka->write_resampler);
            }

			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Stopping Oreka recording for audio stream\n");
			oreka_send_sip_message(oreka, FS_OREKA_STOP, FS_OREKA_READ);
            if (!oreka->mux_streams) {
                oreka_send_sip_message(oreka, FS_OREKA_STOP, FS_OREKA_WRITE);
            }
		}
		break;
	case SWITCH_ABC_TYPE_READ_REPLACE:
    case SWITCH_ABC_TYPE_READ_PING:
		{
			if (pcmu_frame.datalen) {
				if (switch_rtp_write_frame(oreka->read_rtp_stream, &pcmu_frame) > 0) {
					oreka->read_cnt++;
					if (oreka->read_cnt < 10) {
						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Oreka wrote %u bytes! (read)\n", pcmu_frame.datalen);
					}
				} else {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to write %u bytes! (read)\n", pcmu_frame.datalen);
				}
			}
		}
		break;
	case SWITCH_ABC_TYPE_WRITE_REPLACE:
		{
			if (pcmu_frame.datalen) {
				if (switch_rtp_write_frame(oreka->write_rtp_stream, &pcmu_frame) > 0) {
					oreka->write_cnt++;
					if (oreka->write_cnt < 10) {
						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Oreka wrote %u bytes! (write)\n", pcmu_frame.datalen);
					}
				} else {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to write %u bytes! (write)\n", pcmu_frame.datalen);
				}
			}
		}
        break;
	default:
		break;
	}

	return SWITCH_TRUE;
}
Exemplo n.º 11
0
static void compliance_tests(int log_audio)
{
    SNDFILE *outhandle;
    power_meter_t power_meter;
    int outframes;
    int i;
    int block;
    int pre;
    int post;
    int post_post;
    int alaw_failures;
    int ulaw_failures;
    float worst_alaw;
    float worst_ulaw;
    float tmp;
    int len;
    g711_state_t *enc_state;
    g711_state_t *transcode;
    g711_state_t *dec_state;

    outhandle = NULL;
    if (log_audio)
    {
        if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot create audio file '%s'\n", OUT_FILE_NAME);
            exit(2);
        }
    }

    printf("Conversion accuracy tests.\n");
    alaw_failures = 0;
    ulaw_failures = 0;
    worst_alaw = 0.0;
    worst_ulaw = 0.0;
    for (block = 0;  block < 1;  block++)
    {
        for (i = 0;  i < 65536;  i++)
        {
            pre = i - 32768;
            post = alaw_to_linear(linear_to_alaw(pre));
            if (abs(pre) > 140)
            {
                tmp = (float) abs(post - pre)/(float) abs(pre);
                if (tmp > 0.10)
                {
                    printf("A-law: Excessive error at %d (%d)\n", pre, post);
                    alaw_failures++;
                }
                if (tmp > worst_alaw)
                    worst_alaw = tmp;
            }
            else
            {
                /* Small values need different handling for sensible measurement */
                if (abs(post - pre) > 15)
                {
                    printf("A-law: Excessive error at %d (%d)\n", pre, post);
                    alaw_failures++;
                }
            }
            amp[i] = post;
        }
        if (log_audio)
        {
            outframes = sf_writef_short(outhandle, amp, 65536);
            if (outframes != 65536)
            {
                fprintf(stderr, "    Error writing audio file\n");
                exit(2);
            }
        }
        for (i = 0;  i < 65536;  i++)
        {
            pre = i - 32768;
            post = ulaw_to_linear(linear_to_ulaw(pre));
            if (abs(pre) > 40)
            {
                tmp = (float) abs(post - pre)/(float) abs(pre);
                if (tmp > 0.10)
                {
                    printf("u-law: Excessive error at %d (%d)\n", pre, post);
                    ulaw_failures++;
                }
                if (tmp > worst_ulaw)
                    worst_ulaw = tmp;
            }
            else
            {
                /* Small values need different handling for sensible measurement */
                if (abs(post - pre) > 4)
                {
                    printf("u-law: Excessive error at %d (%d)\n", pre, post);
                    ulaw_failures++;
                }
            }
            amp[i] = post;
        }
        if (log_audio)
        {
            outframes = sf_writef_short(outhandle, amp, 65536);
            if (outframes != 65536)
            {
                fprintf(stderr, "    Error writing audio file\n");
                exit(2);
            }
        }
    }
    printf("Worst A-law error (ignoring small values) %f%%\n", worst_alaw*100.0);
    printf("Worst u-law error (ignoring small values) %f%%\n", worst_ulaw*100.0);
    if (alaw_failures  ||  ulaw_failures)
    {
        printf("%d A-law values with excessive error\n", alaw_failures);
        printf("%d u-law values with excessive error\n", ulaw_failures);
        printf("Tests failed\n");
        exit(2);
    }

    printf("Cyclic conversion repeatability tests.\n");
    /* Find what happens to every possible linear value after a round trip. */
    for (i = 0;  i < 65536;  i++)
    {
        pre = i - 32768;
        /* Make a round trip */
        post = alaw_to_linear(linear_to_alaw(pre));
        /* A second round trip should cause no further change */
        post_post = alaw_to_linear(linear_to_alaw(post));
        if (post_post != post)
        {
            printf("A-law second round trip mismatch - at %d, %d != %d\n", pre, post, post_post);
            printf("Tests failed\n");
            exit(2);
        }
        /* Make a round trip */
        post = ulaw_to_linear(linear_to_ulaw(pre));
        /* A second round trip should cause no further change */
        post_post = ulaw_to_linear(linear_to_ulaw(post));
        if (post_post != post)
        {
            printf("u-law round trip mismatch - at %d, %d != %d\n", pre, post, post_post);
            printf("Tests failed\n");
            exit(2);
        }
    }

    printf("Reference power level tests.\n");
    power_meter_init(&power_meter, 7);

    for (i = 0;  i < 8000;  i++)
    {
        amp[i] = ulaw_to_linear(ulaw_1khz_sine[i & 7]);
        power_meter_update(&power_meter, amp[i]);
    }
    printf("Reference u-law 1kHz tone is %fdBm0\n", power_meter_current_dbm0(&power_meter));
    if (log_audio)
    {
        outframes = sf_writef_short(outhandle, amp, 8000);
        if (outframes != 8000)
        {
            fprintf(stderr, "    Error writing audio file\n");
            exit(2);
        }
    }
    if (0.1f < fabs(power_meter_current_dbm0(&power_meter)))
    {
        printf("Test failed.\n");
        exit(2);
    }

    for (i = 0;  i < 8000;  i++)
    {
        amp[i] = alaw_to_linear(alaw_1khz_sine[i & 7]);
        power_meter_update(&power_meter, amp[i]);
    }
    printf("Reference A-law 1kHz tone is %fdBm0\n", power_meter_current_dbm0(&power_meter));
    if (log_audio)
    {
        outframes = sf_writef_short(outhandle, amp, 8000);
        if (outframes != 8000)
        {
            fprintf(stderr, "    Error writing audio file\n");
            exit(2);
        }
    }
    if (0.1f < fabs(power_meter_current_dbm0(&power_meter)))
    {
        printf("Test failed.\n");
        exit(2);
    }

    /* Check the transcoding functions. */
    printf("Testing transcoding A-law -> u-law -> A-law\n");
    for (i = 0;  i < 256;  i++)
    {
        if (alaw_to_ulaw(ulaw_to_alaw(i)) != i)
        {
            if (abs(alaw_to_ulaw(ulaw_to_alaw(i)) - i) > 1)
            {
                printf("u-law -> A-law -> u-law gave %d -> %d\n", i, alaw_to_ulaw(ulaw_to_alaw(i)));
                printf("Test failed\n");
                exit(2);
            }
        }
    }

    printf("Testing transcoding u-law -> A-law -> u-law\n");
    for (i = 0;  i < 256;  i++)
    {
        if (ulaw_to_alaw(alaw_to_ulaw(i)) != i)
        {
            if (abs(alaw_to_ulaw(ulaw_to_alaw(i)) - i) > 1)
            {
                printf("A-law -> u-law -> A-law gave %d -> %d\n", i, ulaw_to_alaw(alaw_to_ulaw(i)));
                printf("Test failed\n");
                exit(2);
            }
        }
    }

    enc_state = g711_init(NULL, G711_ALAW);
    transcode = g711_init(NULL, G711_ALAW);
    dec_state = g711_init(NULL, G711_ULAW);

    len = 65536;
    for (i = 0;  i < len;  i++)
        amp[i] = i - 32768;
    len = g711_encode(enc_state, alaw_data, amp, len);
    len = g711_transcode(transcode, ulaw_data, alaw_data, len);
    len = g711_decode(dec_state, amp, ulaw_data, len);
    if (len != 65536)
    {
        printf("Block coding gave the wrong length - %d instead of %d\n", len, 65536);
        printf("Test failed\n");
        exit(2);
    }
    for (i = 0;  i < len;  i++)
    {
        pre = i - 32768;
        post = amp[i];
        if (abs(pre) > 140)
        {
            tmp = (float) abs(post - pre)/(float) abs(pre);
            if (tmp > 0.10)
            {
                printf("Block: Excessive error at %d (%d)\n", pre, post);
                exit(2);
            }
        }
        else
        {
            /* Small values need different handling for sensible measurement */
            if (abs(post - pre) > 15)
            {
                printf("Block: Excessive error at %d (%d)\n", pre, post);
                exit(2);
            }
        }
    }
    g711_release(enc_state);
    g711_release(transcode);
    g711_release(dec_state);

    if (log_audio)
    {
        if (sf_close_telephony(outhandle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", OUT_FILE_NAME);
            exit(2);
        }
    }

    printf("Tests passed.\n");
}
Exemplo n.º 12
0
/*
 * Initialize the audio device.
 */
void
sun_audio_init( void )
{
	audio_info_t		info;
	char			*audiodev, *acdev;
	int			linval;

	audiodev = getenv("AUDIODEV");
	if (audiodev == NULL || 
	    strncmp("/dev/", audiodev, 5) || 
	    strstr(audiodev, "/../") )
		audiodev = "/dev/audio";

	acdev = malloc(strlen(audiodev) + 4);
	if (acdev == NULL)
	{
		perror("Can't allocate audio control filename");
		exit(1);
	}
	strcpy(acdev, audiodev);
	strcat(acdev, "ctl");

	aucfd = open(acdev, O_WRONLY, 0);
	if (aucfd < 0)
	{
		perror(acdev);
		exit(1);
	}
	free(acdev);

	aufd = open(audiodev, O_WRONLY, 0);
	if (aufd < 0)
	{
		perror(audiodev);
		exit(1);
	}

	signal(SIGALRM, dummy);

	/*
	 * Try to set the device to CD-style audio; we can process it
	 * with the least CPU overhead.
	 */
	AUDIO_INITINFO(&info);
	info.play.sample_rate = 44100;
	info.play.channels = 2;
	info.play.precision = 16;
	info.play.encoding = AUDIO_ENCODING_LINEAR;
	info.play.pause = 0;
	info.record.pause = 0;
	info.monitor_gain = 0;

	if (ioctl(aufd, AUDIO_SETINFO, &info) < 0)
		if (errno == EINVAL)
		{
			/*
			 * Oh well, so much for that idea.
			 */
			AUDIO_INITINFO(&info);
			info.play.sample_rate = 8000;
			info.play.channels = 1;
			info.play.precision = 8;
			info.play.encoding = AUDIO_ENCODING_ULAW;
			info.play.pause = 0;
			info.record.pause = 0;
			info.monitor_gain = 0;
			if (ioctl(aufd, AUDIO_SETINFO, &info) < 0)
			{
				perror("Can't set up audio device");
				exit(1);
			}

			/*
			 * Initialize the linear-to-ulaw mapping table.
			 */
			if (ulawmap == NULL)
				ulawmap = malloc(65536);
			if (ulawmap == NULL)
			{
				perror("malloc");
				exit(1);
			}
			for (linval = 0; linval < 65536; linval++)
				ulawmap[linval] = linear_to_ulaw(linval-32768);
			ulawmap += 32768;
			raw_audio = 0;
		}
		else
		{
			perror(audiodev);
			exit(1);
		}
}
Exemplo n.º 13
0
int main(int argc, char *argv[])
{
    AFfilehandle outhandle;
    AFfilesetup filesetup;
    power_meter_t power_meter;
    int outframes;
    int i;
    int block;
    int pre;
    int post;
    int alaw_failures;
    int ulaw_failures;
    float worst_alaw;
    float worst_ulaw;
    float tmp;
    
    if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP)
    {
        fprintf(stderr, "    Failed to create file setup\n");
        exit(2);
    }
    afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16);
    afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE);
    afInitFileFormat(filesetup, AF_FILE_WAVE);
    afInitChannels(filesetup, AF_DEFAULT_TRACK, 1);

    if ((outhandle = afOpenFile(OUT_FILE_NAME, "w", filesetup)) == AF_NULL_FILEHANDLE)
    {
        fprintf(stderr, "    Cannot create wave file '%s'\n", OUT_FILE_NAME);
        exit(2);
    }

    printf("Conversion accuracy tests.\n");
    alaw_failures = 0;
    ulaw_failures = 0;
    worst_alaw = 0.0;
    worst_ulaw = 0.0;
    for (block = 0;  block < 1;  block++)
    {
        for (i = 0;  i < 65536;  i++)
        {
            pre = i - 32768;
            post = alaw_to_linear(linear_to_alaw(pre));
            if (abs(pre) > 140)
            {
                tmp = (float) abs(post - pre)/(float) abs(pre);
                if (tmp > 0.10)
                {
                    printf("A-law: Excessive error at %d (%d)\n", pre, post);
                    alaw_failures++;
                }
                if (tmp > worst_alaw)
                    worst_alaw = tmp;
            }
            else
            {
                /* Small values need different handling for sensible measurement */
                if (abs(post - pre) > 15)
                {
                    printf("A-law: Excessive error at %d (%d)\n", pre, post);
                    alaw_failures++;
                }
            }
            amp[i] = post;
        }
        outframes = afWriteFrames(outhandle,
                                  AF_DEFAULT_TRACK,
                                  amp,
                                  65536);
        if (outframes != 65536)
        {
            fprintf(stderr, "    Error writing wave file\n");
            exit(2);
        }
        for (i = 0;  i < 65536;  i++)
        {
            pre = i - 32768;
            post = ulaw_to_linear(linear_to_ulaw(pre));
            if (abs(pre) > 40)
            {
                tmp = (float) abs(post - pre)/(float) abs(pre);
                if (tmp > 0.10)
                {
                    printf("u-law: Excessive error at %d (%d)\n", pre, post);
                    ulaw_failures++;
                }
                if (tmp > worst_ulaw)
                    worst_ulaw = tmp;
            }
            else
            {
                /* Small values need different handling for sensible measurement */
                if (abs(post - pre) > 4)
                {
                    printf("u-law: Excessive error at %d (%d)\n", pre, post);
                    ulaw_failures++;
                }
            }
            amp[i] = post;
        }
        outframes = afWriteFrames(outhandle,
                                  AF_DEFAULT_TRACK,
                                  amp,
                                  65536);
        if (outframes != 65536)
        {
            fprintf(stderr, "    Error writing wave file\n");
            exit(2);
        }
    }
    printf("Worst A-law error (ignoring small values) %f%%\n", worst_alaw*100.0);
    printf("Worst u-law error (ignoring small values) %f%%\n", worst_ulaw*100.0);
    if (alaw_failures  ||  ulaw_failures)
    {
        printf("%d A-law values with excessive error\n", alaw_failures);
        printf("%d u-law values with excessive error\n", ulaw_failures);
        printf("Tests failed\n");
        exit(2);
    }
    
    printf("Reference power level tests.\n");
    power_meter_init(&power_meter, 7);

    for (i = 0;  i < 8000;  i++)
    {
        amp[i] = ulaw_to_linear(ulaw_1khz_sine[i & 7]);
        power_meter_update(&power_meter, amp[i]);
    }
    printf("Reference u-law 1kHz tone is %fdBm0\n", power_meter_dbm0(&power_meter));
    outframes = afWriteFrames(outhandle,
                              AF_DEFAULT_TRACK,
                              amp,
                              8000);
    if (outframes != 8000)
    {
        fprintf(stderr, "    Error writing wave file\n");
        exit(2);
    }
    if (0.1f < fabs(power_meter_dbm0(&power_meter)))
    {
        printf("Test failed.\n");
        exit(2);
    }

    for (i = 0;  i < 8000;  i++)
    {
        amp[i] = alaw_to_linear(alaw_1khz_sine[i & 7]);
        power_meter_update(&power_meter, amp[i]);
    }
    printf("Reference A-law 1kHz tone is %fdBm0\n", power_meter_dbm0(&power_meter));
    outframes = afWriteFrames(outhandle,
                              AF_DEFAULT_TRACK,
                              amp,
                              8000);
    if (outframes != 8000)
    {
        fprintf(stderr, "    Error writing wave file\n");
        exit(2);
    }
    if (0.1f < fabs(power_meter_dbm0(&power_meter)))
    {
        printf("Test failed.\n");
        exit(2);
    }

    /* Check the transcoding functions. */
    printf("Testing transcoding A-law -> u-law -> A-law\n");
    for (i = 0;  i < 256;  i++)
    {
        if (alaw_to_ulaw(ulaw_to_alaw(i)) != i)
        {
            if (abs(alaw_to_ulaw(ulaw_to_alaw(i)) - i) > 1)
            {
                printf("u-law -> A-law -> u-law gave %d -> %d\n", i, alaw_to_ulaw(ulaw_to_alaw(i)));
                printf("Test failed\n");
                exit(2);
            }
        }
    }

    printf("Testing transcoding u-law -> A-law -> u-law\n");
    for (i = 0;  i < 256;  i++)
    {
        if (ulaw_to_alaw(alaw_to_ulaw(i)) != i)
        {
            if (abs(alaw_to_ulaw(ulaw_to_alaw(i)) - i) > 1)
            {
                printf("A-law -> u-law -> A-law gave %d -> %d\n", i, ulaw_to_alaw(alaw_to_ulaw(i)));
                printf("Test failed\n");
                exit(2);
            }
        }
    }
    
    if (afCloseFile(outhandle))
    {
        fprintf(stderr, "    Cannot close wave file '%s'\n", OUT_FILE_NAME);
        exit(2);
    }
    afFreeFileSetup(filesetup);

    printf("Tests passed.\n");
    return 0;
}
Exemplo n.º 14
0
static switch_bool_t oreka_core_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type, oreka_stream_type_t stype, const char *stype_str)
{
	oreka_session_t *oreka = user_data;
	switch_core_session_t *session = oreka->session;
	switch_frame_t pcmu_frame;
	switch_frame_t linear_frame = { 0 };
	switch_status_t status = SWITCH_STATUS_SUCCESS;
	uint8_t pcmu_data[SWITCH_RECOMMENDED_BUFFER_SIZE];
	uint8_t linear_data[SWITCH_RECOMMENDED_BUFFER_SIZE];
	uint32_t i = 0;
	int16_t *linear_samples = NULL;

	if (type == SWITCH_ABC_TYPE_READ || type == SWITCH_ABC_TYPE_WRITE) {
		memset(&linear_frame, 0, sizeof(linear_frame));
		linear_frame.data = linear_data;
		linear_frame.buflen = sizeof(linear_data);
		status = switch_core_media_bug_read(bug, &linear_frame, SWITCH_TRUE);
		if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error reading media bug: %d\n", status);
			goto done;
		}
		if (!linear_frame.datalen) {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Linear frame with no length!\n");
			goto done;
		}
		/* convert the L16 frame into PCMU */
		linear_samples = linear_frame.data;
		memset(&pcmu_frame, 0, sizeof(pcmu_frame));
		for (i = 0; i < linear_frame.datalen/sizeof(int16_t); i++) {
			pcmu_data[i] = linear_to_ulaw(linear_samples[i]);
		}
		pcmu_frame.source = __FUNCTION__;
		pcmu_frame.data = pcmu_data;
		pcmu_frame.datalen = i; 
		pcmu_frame.payload = 0;
	}

	switch (type) {
	case SWITCH_ABC_TYPE_INIT:
		{
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Starting Oreka recording for %s stream\n", stype_str);
			oreka_send_sip_message(oreka, FS_OREKA_START, stype);
		}
		break;
	case SWITCH_ABC_TYPE_CLOSE:
		{
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Stopping Oreka recording for %s stream\n", stype_str);
			oreka_send_sip_message(oreka, FS_OREKA_STOP, stype);
		}
		break;
	case SWITCH_ABC_TYPE_READ:
		{
			if (pcmu_frame.datalen) {
				if (switch_rtp_write_frame(oreka->read_rtp_stream, &pcmu_frame) > 0) {
					oreka->read_cnt++;
					if (oreka->read_cnt < 10) {
						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Oreka wrote %u bytes! (read)\n", pcmu_frame.datalen);
					}
				} else {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to write %u bytes! (read)\n", pcmu_frame.datalen);
				}
			}
		}
		break;
	case SWITCH_ABC_TYPE_WRITE:
		{
			if (pcmu_frame.datalen) {
				if (switch_rtp_write_frame(oreka->write_rtp_stream, &pcmu_frame) > 0) {
					oreka->write_cnt++;
					if (oreka->write_cnt < 10) {
						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Oreka wrote %u bytes! (write)\n", pcmu_frame.datalen);
					}
				} else {
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to write %u bytes! (write)\n", pcmu_frame.datalen);
				}
			}
		}
		break;
	default:
		break;
	}
done:
	return SWITCH_TRUE;
}
Exemplo n.º 15
0
static switch_status_t switch_dahdi_encode(switch_codec_t *codec,
										   switch_codec_t *other_codec,
										   void *decoded_data,
										   uint32_t decoded_data_len,
										   uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate,
										   unsigned int *flag)
{
	int32_t res;
	short *dbuf_linear;
	unsigned char *ebuf_g729;
	unsigned char ebuf_ulaw[decoded_data_len / 2];
	uint32_t i;
	struct dahdi_context *context = NULL;
	switch_status_t status;

#ifdef DEBUG_DAHDI_CODEC
	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Switch DAHDI encode called to encode %d bytes.\n", decoded_data_len);
#endif
	context = codec->private_info;

	if (context->encoding_fd == -1) {
		if ((status = init_encoder(codec)) != SWITCH_STATUS_SUCCESS) {
			return status;
		}
	}

	dbuf_linear = decoded_data;
	ebuf_g729 = encoded_data;
	for (i = 0; i < decoded_data_len / sizeof(short); i++) {
		ebuf_ulaw[i] = linear_to_ulaw(dbuf_linear[i]);
	}
#ifdef DEBUG_DAHDI_CODEC
	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Writing %d bytes of decoded ulaw data.\n", i);
#endif
	res = write(context->encoding_fd, ebuf_ulaw, i);
	if (-1 == res) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to write to %s encoder device.\n", transcoder_name);
		return SWITCH_STATUS_FALSE;
	}
	if (i != res) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Requested to write %d bytes to %s encoder device, but only wrote %d bytes.\n", i,
						  transcoder_name, res);
		return SWITCH_STATUS_FALSE;
	}
	res = wait_for_transcoder(context->encoding_fd);
	if (-1 == res) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to poll on %s encoder device: %s.\n", transcoder_name, strerror(errno));
		return SWITCH_STATUS_FALSE;
	}
	if (0 == res) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output on %s encoder device.\n", transcoder_name);
		*encoded_data_len = 0;
		return SWITCH_STATUS_SUCCESS;
	}
#ifdef DEBUG_DAHDI_CODEC
	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Attempting to read %d bytes of encoded data.\n", *encoded_data_len);
#endif
	res = read(context->encoding_fd, encoded_data, *encoded_data_len);
	if (-1 == res) {
		if (EAGAIN == errno || EWOULDBLOCK == errno) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output on %s encoder device (%s).\n", transcoder_name, strerror(errno));
			*encoded_data_len = 0;
			return SWITCH_STATUS_SUCCESS;
		}
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read from %s encoder device: %s.\n", transcoder_name, strerror(errno));
		return SWITCH_STATUS_FALSE;
	}
	*encoded_data_len = res;
#ifdef DEBUG_DAHDI_CODEC
	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Read %d bytes of encoded data.\n", res);
#endif
	return SWITCH_STATUS_SUCCESS;
}
Exemplo n.º 16
0
static switch_status_t switch_sangoma_encode(switch_codec_t *codec, switch_codec_t *other_codec,	/* codec that was used by the other side */
										  void *decoded_data,	/* decoded data that we must encode */
										  uint32_t decoded_data_len /* decoded data length */ ,
										  uint32_t decoded_rate /* rate of the decoded data */ ,
										  void *encoded_data,	/* here we will store the encoded data */
										  uint32_t *encoded_data_len,	/* here we will set the length of the encoded data */
										  uint32_t *encoded_rate /* here we will set the rate of the encoded data */ ,
										  unsigned int *flag /* frame flag, see switch_frame_flag_enum_t */ )
{
	/* FS core checks the actual samples per second and microseconds per packet to determine the buffer size in the worst case scenario, no need to check
	 * whether the buffer passed in by the core (encoded_data) will be big enough */
	switch_frame_t ulaw_frame;
	switch_frame_t encoded_frame;
	switch_status_t sres;
	switch_time_t now_time, difftime;
	unsigned char ebuf_ulaw[decoded_data_len / 2];
	short *dbuf_linear;
	int i = 0;
	int res = 0;
	struct sangoma_transcoding_session *sess = codec->private_info;

	/* start assuming we will not encode anything */
	*encoded_data_len = 0;

	/* initialize on first use */
	if (!sess->encoder.txrtp) {
		int err = 0;
		switch_mutex_lock(g_sessions_lock);
		err = sngtc_create_transcoding_session(&sess->encoder.request, &sess->encoder.reply, 0);
		if (err) {
			memset(&sess->encoder, 0, sizeof(sess->encoder));
			switch_mutex_unlock(g_sessions_lock);
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create Sangoma encoding session.\n");
			return SWITCH_STATUS_FALSE;
		}
		sess->encoder.txrtp = sess->encoder.reply.tx_fd;
		sess->encoder.rxrtp = sess->encoder.reply.rx_fd;
		switch_mutex_unlock(g_sessions_lock);
	}

	/* transcode to ulaw first */
	dbuf_linear = decoded_data;

	for (i = 0; i < decoded_data_len / sizeof(short); i++) {
		ebuf_ulaw[i] = linear_to_ulaw(dbuf_linear[i]);
	}
	
	/* do the writing */
	memset(&ulaw_frame, 0, sizeof(ulaw_frame));	
	ulaw_frame.source = __FUNCTION__;
	ulaw_frame.data = ebuf_ulaw;
	ulaw_frame.datalen = i;
	ulaw_frame.payload = IANA_ULAW;

	res = switch_rtp_write_frame(sess->encoder.txrtp, &ulaw_frame);
	if (-1 == res) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to write to Sangoma encoder RTP session.\n");
		return SWITCH_STATUS_FALSE;
	}

	if (res < i) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, 
				"Requested to write %d bytes to Sangoma encoder RTP session, but wrote %d bytes.\n", i, res);
		return SWITCH_STATUS_FALSE;
	}
	sess->encoder.tx++;

	/* do the reading */
	for ( ; ; ) {
		sres = switch_rtp_zerocopy_read_frame(sess->encoder.rxrtp, &encoded_frame, SWITCH_IO_FLAG_NOBLOCK);
		if (sres == SWITCH_STATUS_GENERR) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read on Sangoma encoder RTP session: %d\n", sres);
			return SWITCH_STATUS_FALSE;
		}

		if (0 == encoded_frame.datalen) {
			break;
		}

		if (encoded_frame.payload != codec->implementation->ianacode
		    && encoded_frame.payload != IANACODE_CN) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Read unexpected payload %d in Sangoma encoder RTP session, expecting %d\n",
					encoded_frame.payload, codec->implementation->ianacode);
			break;
		}

		if (*encoded_data_len) {
			sess->encoder.rxdiscarded++;
		}

		memcpy(encoded_data, encoded_frame.data, encoded_frame.datalen);
		*encoded_data_len = encoded_frame.datalen;
	}

	/* update encoding stats */
	sess->encoder.rx++;

	now_time = switch_micro_time_now();
	if (!sess->encoder.last_rx_time) {
		sess->encoder.last_rx_time = now_time;
	} else {
		difftime = now_time - sess->encoder.last_rx_time;
		sess->encoder.avgrxus = sess->encoder.avgrxus ? ((sess->encoder.avgrxus + difftime)/2) : difftime;
		sess->encoder.last_rx_time  = now_time;
	}

	/* check sequence and bump lost rx packets count if needed */
	if (sess->encoder.lastrxseqno >= 0) {
		if (encoded_frame.seq > (sess->encoder.lastrxseqno + 2) ) {
			sess->encoder.rxlost += encoded_frame.seq - sess->encoder.lastrxseqno - 1;
		}
	}
	sess->encoder.lastrxseqno = encoded_frame.seq;

	return SWITCH_STATUS_SUCCESS;
}
Exemplo n.º 17
0
void client_run(int client_socket, char *local_ip, int local_port, char *remote_ip, int remote_port)
{
    char sendbuf[RCVBUFSIZE], recvbuf[RCVBUFSIZE], infobuf[RCVBUFSIZE];
	struct sockaddr_in addr = {0}, sendaddr = {0};
    int read_bytes;
	int usock;
	int reuse_addr = 1;
    fax_state_t fax;
	char tmp[512], fn[512], *file_name = "/tmp/test.tiff";
	int send_fax = FALSE;
	int g711 = 0;
	int pcmu = 0;

	snprintf(sendbuf, sizeof(sendbuf), "connect\n\n");
	send(client_socket, sendbuf, strlen(sendbuf), 0);

    if ((read_bytes = recv(client_socket, infobuf, sizeof(infobuf), 0)) < 0) {
        die("recv() failed");
	}

#if SOCKET2ME_DEBUG
	printf("READ [%s]\n", infobuf);
#endif

	if (cheezy_get_var(infobuf, "Channel-Read-Codec-Name", tmp, sizeof(tmp))) {
		if (!strcasecmp(tmp, "pcmu")) {
			g711 = 1;
			pcmu = 1;
		} else if (!strcasecmp(tmp, "pcma")) {
			g711 = 1;
		}
	}


	snprintf(sendbuf, sizeof(sendbuf), "sendmsg\n"
			 "call-command: unicast\n"
			 "local-ip: %s\n"
			 "local-port: %d\n"
			 "remote-ip: %s\n"
			 "remote-port: %d\n"
			 "transport: udp\n"
			 "%s"
			 "\n",
			 local_ip, local_port,
			 remote_ip, remote_port,
			 g711 ? "flags: native\n" : ""
			 );

	
	if (cheezy_get_var(infobuf, "variable_fax_file_name", fn, sizeof(fn))) {
		file_name = fn;
	}

	if (cheezy_get_var(infobuf, "variable_fax_mode", tmp, sizeof(tmp))) {
		if (!strcasecmp(tmp, "send")) {
			send_fax = TRUE;
		}
	}

	if (cheezy_get_var(infobuf, "variable_fax_preexec", tmp, sizeof(tmp))) {
	  set_vars(infobuf);
	  system(tmp);
	}

#if SOCKET2ME_DEBUG
	printf("SEND: [%s]\n", sendbuf);
#endif
	send(client_socket, sendbuf, strlen(sendbuf), 0);

	memset(recvbuf, 0, sizeof(recvbuf));
    if ((read_bytes = recv(client_socket, recvbuf, sizeof(recvbuf), 0)) < 0) {
        die("recv() failed");
	}
#if SOCKET2ME_DEBUG
	printf("READ [%s]\n", recvbuf);
#endif
	
	if ((usock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
        die("socket() failed");
	}

	setsockopt(usock, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr));

    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    /*addr.sin_addr.s_addr = inet_addr(remote_ip);*/
    addr.sin_port = htons(remote_port);

    sendaddr.sin_family = AF_INET;
    sendaddr.sin_addr.s_addr = inet_addr(local_ip);
    sendaddr.sin_port = htons(local_port);
	
    if (bind(usock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        die("bind() failed");
	}

	printf("%s Fax filename: [%s] from %s:%d -> %s:%d\n", send_fax ? "Sending" : "Receiving", file_name, local_ip, local_port, remote_ip, remote_port);
	
    fax_init(&fax, send_fax);
    t30_set_local_ident(&fax.t30_state, "Socket 2 ME");
    t30_set_header_info(&fax.t30_state, "Socket 2 ME");
	if (send_fax) {
		t30_set_tx_file(&fax.t30_state, file_name, -1, -1);
	} else {
		t30_set_rx_file(&fax.t30_state, file_name, -1);
	}
    t30_set_phase_b_handler(&fax.t30_state, phase_b_handler, NULL);
    t30_set_phase_d_handler(&fax.t30_state, phase_d_handler, NULL);
    t30_set_phase_e_handler(&fax.t30_state, phase_e_handler, NULL);
    t30_set_document_handler(&fax.t30_state, document_handler, NULL);

    t30_set_ecm_capability(&fax.t30_state, TRUE);
    t30_set_supported_compressions(&fax.t30_state, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);

    t30_set_supported_image_sizes(&fax.t30_state, T30_SUPPORT_US_LETTER_LENGTH | T30_SUPPORT_US_LEGAL_LENGTH | T30_SUPPORT_UNLIMITED_LENGTH
                                  | T30_SUPPORT_215MM_WIDTH | T30_SUPPORT_255MM_WIDTH | T30_SUPPORT_303MM_WIDTH);
    t30_set_supported_resolutions(&fax.t30_state, T30_SUPPORT_STANDARD_RESOLUTION | T30_SUPPORT_FINE_RESOLUTION | T30_SUPPORT_SUPERFINE_RESOLUTION
                                  | T30_SUPPORT_R8_RESOLUTION | T30_SUPPORT_R16_RESOLUTION);

	for (;;) {
		struct sockaddr_in local_addr = {0};
        size_t cliAddrLen = sizeof(local_addr);
		unsigned char audiobuf[1024], rawbuf[1024], outbuf[1024];
		short *usebuf = NULL;
		int tx, tx_bytes, bigger, sample_count;
		fd_set ready;

		FD_ZERO(&ready);

		FD_SET(usock, &ready);
		FD_SET(client_socket, &ready);
		
		bigger = usock > client_socket ? usock : client_socket;
		select(++bigger, &ready, NULL, NULL, NULL);
		
		if (FD_ISSET(client_socket, &ready)) {
			memset(recvbuf, 0, sizeof(recvbuf));
			if ((read_bytes = recv(client_socket, recvbuf, sizeof(recvbuf), 0)) < 0) {
				die("recv() failed");
			}

			if (read_bytes == 0) {
				break;
			}
#if SOCKET2ME_DEBUG
			printf("READ [%s]\n", recvbuf);
#endif
		}

		if (!FD_ISSET(usock, &ready)) {
			continue;
		}

        if ((read_bytes = recvfrom(usock, audiobuf, sizeof(audiobuf), 0, (struct sockaddr *) &local_addr, &cliAddrLen)) < 0) {
			die("recvfrom() failed");
		}

		if (g711) {
			int i;
			short *rp = (short *) rawbuf;
			
			for (i = 0; i < read_bytes; i++) {
				if (pcmu) {
					rp[i] = ulaw_to_linear(audiobuf[i]);
				} else {
					rp[i] = alaw_to_linear(audiobuf[i]);
				}
			}
			usebuf = rp;
			sample_count = read_bytes;
		} else {
			usebuf = (short *) audiobuf;
			sample_count = read_bytes / 2;
		}
		
		fax_rx(&fax, usebuf, sample_count);
#if SOCKET2ME_DEBUG
		printf("Handling client %s:%d %d bytes\n", inet_ntoa(local_addr.sin_addr), ntohs(local_addr.sin_port), read_bytes);
#endif

		
		if ((tx = fax_tx(&fax, (short *)outbuf, sample_count)) < 0) {
            printf("Fax Error\n");
			break;
        } else if (!tx) {
			continue;
		}
		

		if (g711) {
			int i;
			short *bp = (short *) outbuf;
			for (i = 0; i < tx; i++) {
				if (pcmu) {
					rawbuf[i] = linear_to_ulaw(bp[i]);
				} else {
					rawbuf[i] = linear_to_alaw(bp[i]);
				}
			}
			usebuf = (short *) rawbuf;
			tx_bytes = tx;
		} else {
			usebuf = (short *)outbuf;
			tx_bytes = tx * 2;
		}	
		

		cliAddrLen = sizeof(sendaddr);
        if (sendto(usock, usebuf, tx_bytes, 0, (struct sockaddr *) &sendaddr, sizeof(sendaddr)) != tx_bytes) {
			die("sendto() sent a different number of bytes than expected");
		}
	}

	close(client_socket);
	close(usock);
		
    t30_terminate(&fax.t30_state);
    fax_release(&fax);

    if (cheezy_get_var(infobuf, "variable_fax_postexec", tmp, sizeof(tmp))) {
      set_vars(infobuf);
      system(tmp);
    }
	printf("Done\n");
	snprintf(sendbuf, sizeof(sendbuf), "hangup\n\n");
	send(client_socket, sendbuf, strlen(sendbuf), 0);
	
}