Ejemplo n.º 1
0
void
enc_slinear_8(int fd, audio_encoding_t *enc, int chans, int rate)
{
	audio_info_t inf;
	struct ausrate rt;
	int8_t *samples = NULL, *p;
	int i, j;

	AUDIO_INITINFO(&inf);
	inf.play.precision = enc->precision;
	inf.play.encoding = enc->encoding;
	inf.play.channels = chans;
	inf.play.sample_rate = rate;; 

	if (ioctl(fd, AUDIO_SETINFO, &inf) == -1) {
		printf("[%s]", strerror(errno));
		goto out;
	}

	if (ioctl(fd, AUDIO_GETINFO, &inf) == -1) {
		printf("[getinfo: %s]", strerror(errno));
		goto out;
	}
	rt.r_rate = inf.play.sample_rate;
	rt.s_rate = inf.play.sample_rate;
	rt.bps = 1 * chans;
	rt.bytes = inf.play.sample_rate * chans * PLAYSECS;

	samples = (int8_t *)malloc(inf.play.sample_rate * chans);
	if (samples == NULL) {
		warn("malloc");
		goto out;
	}

	for (i = 0, p = samples; i < inf.play.sample_rate; i++) {
		float d;
		int8_t v;

		d = 127.0 * sinf(((float)i / (float)inf.play.sample_rate) *
		    (2 * M_PI * playfreq));
		d = rintf(d);
		v = d;

		for (j = 0; j < chans; j++) {
			*p = v;
			p++;
		}
	}

	mark_time(&rt.tv_begin);
	for (i = 0; i < PLAYSECS; i++)
		write(fd, samples, inf.play.sample_rate * chans);
	audio_wait(fd);
	mark_time(&rt.tv_end);
	check_srate(&rt);

out:
	if (samples != NULL)
		free(samples);
}
Ejemplo n.º 2
0
int main(int argc, char **argv) {
    PaStream *stream;
    sound data;
    writer wargs;
    pthread_t file_write_thread, wave_viewer, crude_detector;

    //wunused
    (void) argc;
    (void) argv;

    if (argc >= 2 && *argv[1] == 'r'){
        png_view_create("out/record.dog","waveform.png");
        return 0;
    }


    signal(SIGINT, shutdown);

    wargs.df = create_dogfile("out/record.dog", DF_COMPRESSED, DF_LOSSLESS);
    wargs.data = &data;

    audio_init(&stream, &data);
    audio_start(stream);
    if (pthread_create(&file_write_thread, NULL, file_writer, &wargs)){
        fprintf(stderr, "Error creating file writer\n");
        close();
        close_file(wargs.df);
        exit(1);
    }

    if (argc >= 2 && *argv[1] == 'n'){
        nc_setup();
        if (pthread_create(&wave_viewer, NULL, nc_view, &data)){
            fprintf(stderr, "Error creating waveform viewer\n");
            nc_stop();
            close();
            close_file(wargs.df);
            exit(1);
        }
    }

    detection_start();
    if (pthread_create(&crude_detector, NULL, detect, &data)){
        fprintf(stderr, "Error creating detection thread\n");
        nc_stop();
        close();
        close_file(wargs.df);
        exit(1);
    }

    audio_wait(stream);


    //nc_stop();
    close();
    close_file(wargs.df);

    return 0;
}
Ejemplo n.º 3
0
bool audio_listen_read(audio_t *a, audio_sample_t *samples)
{
    if (!Pa_IsStreamActive(a->rstream))
        return false;

    audio_wait(a);
    PaUtil_ReadRingBuffer(&a->rb, &samples[0], a->samples_per_chunk);

    return true;
}
Ejemplo n.º 4
0
bool audio_record_read(audio_t *a, audio_sample_t *samples)
{
    if(!Pa_IsStreamActive(a->rstream))
        return false;

    audio_wait(a);

    if(!audio_grow(a, a->samples_per_chunk))
        return false;

    PaUtil_ReadRingBuffer(&a->rb, &a->prbuf[a->prbuf_offset], a->samples_per_chunk);
    memcpy(&samples[0], &a->prbuf[a->prbuf_offset], a->samples_per_chunk * sizeof(audio_sample_t));

    a->prbuf_offset = a->prbuf_size;

    return true;
}
Ejemplo n.º 5
0
bool audio_play_read(audio_t *a, audio_sample_t *samples)
{
    // Copy here in case prbuf_offset is modified by the play thread while this
    // function is running.
    size_t offset = a->prbuf_offset;

    // If there aren't enough samples left to make up a chunk, bail.
    if (a->prbuf_size - offset < a->samples_per_chunk)
        return false;

    if (!Pa_IsStreamActive(a->pstream))
        return false;

    audio_wait(a);

    // If we get here, then there are enough samples to make up a chunk, and the
    // user hasn't stopped playback, so copy out the samples for this chunk.
    memcpy(&samples[0], &a->prbuf[offset], a->samples_per_chunk * sizeof(audio_sample_t));

    return true;
}
Ejemplo n.º 6
0
static void xmit_ax25_frames (int c, int p, packet_t pp)
{

  	unsigned char fbuf[AX25_MAX_PACKET_LEN+2];
    	int flen;
	char stemp[1024];	/* max size needed? */
	int info_len;
	unsigned char *pinfo;
	int pre_flags, post_flags;
	int num_bits;		/* Total number of bits in transmission */
				/* including all flags and bit stuffing. */
	int duration;		/* Transmission time in milliseconds. */
	int already;
	int wait_more;

	int maxframe;		/* Maximum number of frames for one transmission. */
	int numframe;		/* Number of frames sent during this transmission. */

/*
 * These are for timing of a transmission.
 * All are in usual unix time (seconds since 1/1/1970) but higher resolution
 */
	double time_ptt;	/* Time when PTT is turned on. */
	double time_now;	/* Current time. */


	int nb;

	maxframe = (p == TQ_PRIO_0_HI) ? 1 : 7;


/*
 * Print trasmitted packet.  Prefix by channel and priority.
 * Do this before we get into the time critical part.
 */
	ax25_format_addrs (pp, stemp);
	info_len = ax25_get_info (pp, &pinfo);
	text_color_set(DW_COLOR_XMIT);
	dw_printf ("[%d%c] ", c, p==TQ_PRIO_0_HI ? 'H' : 'L');
	dw_printf ("%s", stemp);			/* stations followed by : */
	ax25_safe_print ((char *)pinfo, info_len, ! ax25_is_aprs(pp));
	dw_printf ("\n");
	(void)ax25_check_addresses (pp);

/* Optional hex dump of packet. */

	if (g_debug_xmit_packet) {

	  text_color_set(DW_COLOR_DEBUG);
	  dw_printf ("------\n");
	  ax25_hex_dump (pp);
    	  dw_printf ("------\n");
	}

/* 
 * Turn on transmitter.
 * Start sending leading flag bytes.
 */
	time_ptt = dtime_now ();

#if DEBUG
	text_color_set(DW_COLOR_DEBUG);
	dw_printf ("xmit_thread: Turn on PTT now for channel %d. speed = %d\n", c, xmit_bits_per_sec[c]);
#endif
	ptt_set (OCTYPE_PTT, c, 1);

	pre_flags = MS_TO_BITS(xmit_txdelay[c] * 10, c) / 8;
	num_bits =  hdlc_send_flags (c, pre_flags, 0);
#if DEBUG
	text_color_set(DW_COLOR_DEBUG);
	dw_printf ("xmit_thread: txdelay=%d [*10], pre_flags=%d, num_bits=%d\n", xmit_txdelay[c], pre_flags, num_bits);
#endif


/*
 * Transmit the frame.
 */	
	flen = ax25_pack (pp, fbuf);
	assert (flen >= 1 && flen <= sizeof(fbuf));
	nb = hdlc_send_frame (c, fbuf, flen);
	num_bits += nb;
	numframe = 1;
#if DEBUG
	text_color_set(DW_COLOR_DEBUG);
	dw_printf ("xmit_thread: flen=%d, nb=%d, num_bits=%d, numframe=%d\n", flen, nb, num_bits, numframe);
#endif
	ax25_delete (pp);

/*
 * Additional packets if available and not exceeding max.
 */

	while (numframe < maxframe && tq_count (c,p) > 0) {

	  pp = tq_remove (c, p);
#if DEBUG
	 text_color_set(DW_COLOR_DEBUG);
	 dw_printf ("xmit_thread: tq_remove(chan=%d, prio=%d) returned %p\n", c, p, pp);
#endif
	 ax25_format_addrs (pp, stemp);
	 info_len = ax25_get_info (pp, &pinfo);
	 text_color_set(DW_COLOR_XMIT);
	 dw_printf ("[%d%c] ", c, p==TQ_PRIO_0_HI ? 'H' : 'L');
	 dw_printf ("%s", stemp);			/* stations followed by : */
	 ax25_safe_print ((char *)pinfo, info_len, ! ax25_is_aprs(pp));
	 dw_printf ("\n");
	 (void)ax25_check_addresses (pp);

	 if (g_debug_xmit_packet) {
	    text_color_set(DW_COLOR_DEBUG);
	    dw_printf ("------\n");
	    ax25_hex_dump (pp);
    	    dw_printf ("------\n");
	  }

/*
 * Transmit the frame.
 */		
	  flen = ax25_pack (pp, fbuf);
	  assert (flen >= 1 && flen <= sizeof(fbuf));
	  nb = hdlc_send_frame (c, fbuf, flen);
	  num_bits += nb;
	  numframe++;
#if DEBUG
	  text_color_set(DW_COLOR_DEBUG);
	  dw_printf ("xmit_thread: flen=%d, nb=%d, num_bits=%d, numframe=%d\n", flen, nb, num_bits, numframe);
#endif
	  ax25_delete (pp);
	}

/* 
 * Need TXTAIL because we don't know exactly when the sound is done.
 */

	post_flags = MS_TO_BITS(xmit_txtail[c] * 10, c) / 8;
	nb = hdlc_send_flags (c, post_flags, 1);
	num_bits += nb;
#if DEBUG
	text_color_set(DW_COLOR_DEBUG);
	dw_printf ("xmit_thread: txtail=%d [*10], post_flags=%d, nb=%d, num_bits=%d\n", xmit_txtail[c], post_flags, nb, num_bits);
#endif


/* 
 * While demodulating is CPU intensive, generating the tones is not.
 * Example: on the RPi, with 50% of the CPU taken with two receive
 * channels, a transmission of more than a second is generated in
 * about 40 mS of elapsed real time.
 */

	audio_wait(ACHAN2ADEV(c));		

/* 
 * Ideally we should be here just about the time when the audio is ending.
 * However, the innards of "audio_wait" are not satisfactory in all cases.
 *
 * Calculate how long the frame(s) should take in milliseconds.
 */

	duration = BITS_TO_MS(num_bits, c);

/*
 * See how long it has been since PTT was turned on.
 * Wait additional time if necessary.
 */

	time_now = dtime_now();
	already = (int) ((time_now - time_ptt) * 1000.);
	wait_more = duration - already;

#if DEBUG
	text_color_set(DW_COLOR_DEBUG);
	dw_printf ("xmit_thread: xmit duration=%d, %d already elapsed since PTT, wait %d more\n", duration, already, wait_more );
#endif

	if (wait_more > 0) {
	  SLEEP_MS(wait_more);
	}
	else if (wait_more < -100) {

	  /* If we run over by 10 mSec or so, it's nothing to worry about. */
	  /* However, if PTT is still on about 1/10 sec after audio */
	  /* should be done, something is wrong. */

	  /* Looks like a bug with the RPi audio system. Never an issue with Ubuntu.  */
	  /* This runs over randomly sometimes. TODO:  investigate more fully sometime. */
#ifndef __arm__
	  text_color_set(DW_COLOR_ERROR);
	  dw_printf ("Transmit timing error: PTT is on %d mSec too long.\n", -wait_more);
#endif
	}

/*
 * Turn off transmitter.
 */
#if DEBUG
	text_color_set(DW_COLOR_DEBUG);
	time_now = dtime_now();
	dw_printf ("xmit_thread: Turn off PTT now. Actual time on was %d mS, vs. %d desired\n", (int) ((time_now - time_ptt) * 1000.), duration);
#endif
		
	ptt_set (OCTYPE_PTT, c, 0);

} /* end xmit_ax25_frames */