view pcm/pcm_tx.c @ 8:70aa8cbdbde9

pcm: implement pcm-fill command
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 23 Jun 2024 19:30:40 +0000
parents ca351324187a
children e3d16d490ce2
line wrap: on
line source

/*
 * In this module we implement PCM Tx toward the TRAU.
 */

#include <ctype.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <osmocom/core/select.h>

#include "globals.h"

static const uint8_t dmw_alaw[8] =
	{0x34, 0x21, 0x21, 0x34, 0xB4, 0xA1, 0xA1, 0xB4};

static uint8_t pcm_fill_octet = 0x54;
static bool dmw_active;
static uint8_t *play_buffer;
static unsigned play_buf_nframes, play_buf_ptr;

static void fill_with_dmw(uint8_t *buf)
{
	unsigned n;

	for (n = 0; n < 20; n++) {
		memcpy(buf, dmw_alaw, 8);
		buf += 8;
	}
}

static void fill_with_play(uint8_t *outbuf)
{
	memcpy(outbuf, play_buffer + play_buf_ptr * 160, 160);
	play_buf_ptr++;
	if (play_buf_ptr < play_buf_nframes)
		return;
	free(play_buffer);
	play_buffer = 0;
	printf("file play finished\n");
}

void transmit_pcm_20ms(void)
{
	uint8_t buf[160];

	if (play_buffer)
		fill_with_play(buf);
	else if (dmw_active)
		fill_with_dmw(buf);
	else
		memset(buf, pcm_fill_octet, 160);
	write(ts_fd, buf, 160);
}

void cmd_pcm_fill(int argc, char **argv)
{
	u_long val;
	char *cp;

	if (argc != 2) {
		printf("error: pcm-fill command needs 1 argument\n");
		return;
	}
	if (!isxdigit(argv[1][0])) {
inv_arg:	printf("error: argument is not a valid hex octet\n");
		return;
	}
	val = strtoul(argv[1], &cp, 16);
	if (*cp)
		goto inv_arg;
	if (val > 0xFF)
		goto inv_arg;
	pcm_fill_octet = val;
}