view src/g23m-aci/aci/ati_audio.c @ 602:92dbfa906f66

fc-target.cfg config header renamed to more sensible fc-target.h
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 06 Apr 2019 23:54:20 +0000
parents 8f50b202e81f
children 38a65c3a96af
line wrap: on
line source

/*
 * This ATI module and the AT commands implemented therein are a FreeCalypso
 * addition.  The purpose of these AT commands is to exercise the audio
 * capabilities of the firmware - by using these commands, you should be
 * able to emit sounds from the speaker or record voice from the microphone
 * without needing to be in a call, and without bringing up GSM at all.
 *
 * Our corrected implementation of the AT@AUL command (originally added
 * by Openmoko) has been moved into this module as well.
 */

#ifndef ATI_AUDIO_C
#define ATI_AUDIO_C

#include "aci_all.h"

#include <ctype.h>
#include <string.h>

#include "aci_cmh.h"
#include "ati_cmd.h"
#include "aci_cmd.h"
#include "aci_io.h"
#include "aci_cmd.h"
#include "l4_tim.h"
#include "line_edit.h"
#include "aci_lst.h"

#include "pcm.h"
#include "audio.h"
#include "aci.h"
#include "rx.h"
#include "pwr.h"
#include "l4_tim.h"

#ifdef GPRS
#ifdef DTI
#include "dti.h"
#include "dti_conn_mng.h"
#include "dti_cntrl_mng.h"
#endif /* DTI */
#include "gaci.h"
#include "gaci_cmh.h"
#include "gaci_cmd.h"
#endif  /* GPRS */

#include "aci_mem.h"
#include "aci_prs.h"

#include "ati_int.h"

#ifndef _SIMULATION_
#include "ffs/ffs.h"
#endif

#ifdef FF_ATI_BAT

#include "typedefs.h"
#include "gdd.h"
#include "bat.h"

#include "ati_bat.h"

#endif /*FF_ATI_BAT*/

#include "audio/audio_api.h"
#include "audio.h"	/* Condat */

#include "fc-target.h"
#include "armio.h"

#if defined(CONFIG_TARGET_DSAMPLE) || defined(CONFIG_TARGET_FCFAM)
/* AT@SPKR - turn loudspeaker amplifier on or off */
GLOBAL T_ATI_RSLT atAtSPKR ( char *cl, UBYTE srcId )
{
	int state;

	TRACE_FUNCTION("atAtSPKR()");

	cl = parse(cl, "D", &state);
	if (!cl)
		return (ATI_FAIL);
	if (state)
		AI_SetBit(1);
	else
		AI_ResetBit(1);
	return (ATI_CMPL);
}

GLOBAL T_ATI_RSLT queatAtSPKR (char *cl, UBYTE srcId)
{
	char *me="@SPKR: ";
	int state;

	TRACE_FUNCTION("queatAtSPKR()");

	state = AI_ReadBit(1);
	sprintf(g_sa, "%s%d", me, state);

	io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);

	return (ATI_CMPL);
}
#endif

/* AT@SND - emit sound through Condat API */
GLOBAL T_ATI_RSLT atAtSND ( char *cl, UBYTE srcId )
{
	UBYTE sound_id = TONES_KEYBEEP;

	cl = parse(cl, "x", &sound_id);
	audio_PlaySoundID(AUDIO_SPEAKER, sound_id, 0, AUDIO_PLAY_ONCE);
	return (ATI_CMPL);
}

static void audio_callback(void *event_from_audio)
{
	/* do nothing at this time */
}

/*
 * PURPOSE : @AUL command (Audio table load)
 */

static char aul_name[AUDIO_MODE_FILENAME_MAX_SIZE];

GLOBAL T_ATI_RSLT atAtAUL (char *cl, UBYTE srcId)
{
	T_AUDIO_MODE_LOAD aul_param;
	T_RV_RETURN return_path;

	TRACE_FUNCTION("atAtAUL()");

	cl = parse(cl, "S", (LONG)(sizeof(aul_param.audio_mode_filename)),
		   aul_param.audio_mode_filename);
	if (!cl || !aul_param.audio_mode_filename[0])
		return (ATI_FAIL);

	/* Openmoko backward compatibility */
	if (isdigit(aul_param.audio_mode_filename[0]) &&
	    !aul_param.audio_mode_filename[1])
		sprintf(aul_param.audio_mode_filename, "para%c",
			aul_param.audio_mode_filename[0]);

	return_path.addr_id        = NULL;
	return_path.callback_func  = audio_callback;
	if (audio_mode_load(&aul_param, return_path) == AUDIO_OK) {
		strcpy(aul_name, aul_param.audio_mode_filename);
		return (ATI_CMPL);
	} else
		return (ATI_FAIL);
}

GLOBAL T_ATI_RSLT queatAtAUL (char *cl, UBYTE srcId)
{
	char *me="@AUL: ";

	TRACE_FUNCTION("queatAtAUL()");

	if (aul_name[0])
		sprintf(g_sa, "%s/aud/%s.cfg", me, aul_name);
	else
		sprintf(g_sa, "%s", me);

	io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);

	return (ATI_CMPL);
}

#ifdef CONFIG_TARGET_FCMODEM
extern UBYTE aci_digital_voice_autoswitch;

/* AT@VPATH - configure digital voice path */
GLOBAL T_ATI_RSLT atAtVPATH ( char *cl, UBYTE srcId )
{
	int vpath_int;
	T_AUDIO_VOICE_PATH_SETTING vpath;
	T_AUDIO_FULL_ACCESS_WRITE audio_param;
	T_RV_RETURN return_path;

	TRACE_FUNCTION("atAtVPATH()");

	cl = parse(cl, "D", &vpath_int);
	if (!cl)
		return (ATI_FAIL);
	vpath = vpath_int;
	audio_param.variable_indentifier = AUDIO_PATH_USED;
	audio_param.data = &vpath;

	return_path.addr_id        = NULL;
	return_path.callback_func  = audio_callback;
	if (audio_full_access_write(&audio_param, return_path) == AUDIO_OK)
		return (ATI_CMPL);
	else
		return (ATI_FAIL);
}

GLOBAL T_ATI_RSLT queatAtVPATH (char *cl, UBYTE srcId)
{
	char *me="@VPATH: ";
	T_AUDIO_VOICE_PATH_SETTING vpath;
	T_AUDIO_FULL_ACCESS_READ audio_param;

	TRACE_FUNCTION("queatAtVPATH()");

	audio_param.variable_indentifier = AUDIO_PATH_USED;
	audio_param.data = &vpath;
	if (audio_full_access_read(&audio_param) != AUDIO_OK)
		return (ATI_FAIL);

	sprintf(g_sa, "%s%d", me, vpath);

	io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);

	return (ATI_CMPL);
}

/* AT@VSEL - configure digital voice path automatic operation */
GLOBAL T_ATI_RSLT atAtVSEL ( char *cl, UBYTE srcId )
{
	int vsel_int;

	TRACE_FUNCTION("atAtVSEL()");

	cl = parse(cl, "D", &vsel_int);
	if (!cl)
		return (ATI_FAIL);
	if (vsel_int != 0 && vsel_int != 1)
		return (ATI_FAIL);
	aci_digital_voice_autoswitch = vsel_int;
	return (ATI_CMPL);
}

GLOBAL T_ATI_RSLT queatAtVSEL (char *cl, UBYTE srcId)
{
	char *me="@VSEL: ";

	TRACE_FUNCTION("queatAtVSEL()");

	sprintf(g_sa, "%s%u", me, aci_digital_voice_autoswitch);
	io_sendMessage(srcId, g_sa, ATI_NORMAL_OUTPUT);
	return (ATI_CMPL);
}
#endif

static char melody_E1_name[AUDIO_PATH_NAME_MAX_SIZE];

/* AT@E1 - play an E1 format melody */
GLOBAL T_ATI_RSLT atAtE1 ( char *cl, UBYTE srcId )
{
	T_AUDIO_MELODY_E1_PARAMETER e1_param;
	int loopback = 0;
	T_RV_RETURN return_path;

	cl = parse(cl, "Sd", (LONG)(sizeof(e1_param.melody_name)),
		   e1_param.melody_name, &loopback);
	if (!cl || !e1_param.melody_name[0])
		return (ATI_FAIL);
	e1_param.loopback = loopback;
	e1_param.melody_mode = AUDIO_MELODY_NORMAL_MODE;

	return_path.addr_id        = NULL;
	return_path.callback_func  = audio_callback;
	if (audio_melody_E1_start(&e1_param, return_path) == AUDIO_OK) {
		strcpy(melody_E1_name, e1_param.melody_name);
		return (ATI_CMPL);
	} else
		return (ATI_FAIL);
}

/* AT@E1STOP - stop melody started with AT@E1 */
GLOBAL T_ATI_RSLT atAtE1STOP ( char *cl, UBYTE srcId )
{
	T_AUDIO_MELODY_E1_STOP_PARAMETER e1stop_param;
	T_RV_RETURN return_path;

	if (!melody_E1_name[0])
		return (ATI_FAIL);
	strcpy(e1stop_param.melody_name, melody_E1_name);

	return_path.addr_id        = NULL;
	return_path.callback_func  = audio_callback;
	if (audio_melody_E1_stop(&e1stop_param, return_path) == AUDIO_OK)
		return (ATI_CMPL);
	else
		return (ATI_FAIL);
}

static char melody_E2_name[AUDIO_PATH_NAME_MAX_SIZE];

/* AT@E2 - play an E2 format melody */
GLOBAL T_ATI_RSLT atAtE2 ( char *cl, UBYTE srcId )
{
	T_AUDIO_MELODY_E2_PARAMETER e2_param;
	int loopback = 0;
	T_RV_RETURN return_path;

	cl = parse(cl, "Sd", (LONG)(sizeof(e2_param.melody_E2_name)),
		   e2_param.melody_E2_name, &loopback);
	if (!cl || !e2_param.melody_E2_name[0])
		return (ATI_FAIL);
	e2_param.E2_loopback = loopback;
	e2_param.melody_E2_mode = AUDIO_MELODY_NORMAL_MODE;

	return_path.addr_id        = NULL;
	return_path.callback_func  = audio_callback;
	if (audio_melody_E2_start(&e2_param, return_path) == AUDIO_OK) {
		strcpy(melody_E2_name, e2_param.melody_E2_name);
		return (ATI_CMPL);
	} else
		return (ATI_FAIL);
}

/* AT@E2LSI - load melody E2 instrument list file */
GLOBAL T_ATI_RSLT atAtE2LSI ( char *cl, UBYTE srcId )
{
	T_AUDIO_MELODY_E2_LOAD_FILE_INSTR_PARAMETER e2_lsi_param;

	cl = parse(cl, "S", (LONG)(sizeof(e2_lsi_param.melody_E2_file_name)),
		   e2_lsi_param.melody_E2_file_name);
	if (!cl || !e2_lsi_param.melody_E2_file_name[0])
		return (ATI_FAIL);

	if (audio_melody_E2_load_file_instruments(&e2_lsi_param) == AUDIO_OK)
		return (ATI_CMPL);
	else
		return (ATI_FAIL);
}

/* AT@E2STOP - stop melody started with AT@E2 */
GLOBAL T_ATI_RSLT atAtE2STOP ( char *cl, UBYTE srcId )
{
	T_AUDIO_MELODY_E2_STOP_PARAMETER e2stop_param;
	T_RV_RETURN return_path;

	if (!melody_E2_name[0])
		return (ATI_FAIL);
	strcpy(e2stop_param.melody_E2_name, melody_E2_name);

	return_path.addr_id        = NULL;
	return_path.callback_func  = audio_callback;
	if (audio_melody_E2_stop(&e2stop_param, return_path) == AUDIO_OK)
		return (ATI_CMPL);
	else
		return (ATI_FAIL);
}

/* AT@TONE - exercise TONES through RiViera Audio Service API */
GLOBAL T_ATI_RSLT atAtTONE ( char *cl, UBYTE srcId )
{
	int tone_start[3], tone_stop[3], tone_freq[3], tone_ampl[3];
	int frame_dur, sequence_dur, period_dur, repetition;
	int i;
	T_AUDIO_TONES_PARAMETER t;
	T_RV_RETURN return_path;

	cl = parse(cl, "DDDDDDDDDDDDDDDD",
		&tone_start[0], &tone_stop[0], &tone_freq[0], &tone_ampl[0],
		&tone_start[1], &tone_stop[1], &tone_freq[1], &tone_ampl[1],
		&tone_start[2], &tone_stop[2], &tone_freq[2], &tone_ampl[2],
		&frame_dur, &sequence_dur, &period_dur, &repetition);
	if (!cl)
		return (ATI_FAIL);
	for (i = 0; i < 3; i++) {
		t.tones[i].start_tone = tone_start[i];
		t.tones[i].stop_tone = tone_stop[i];
		t.tones[i].frequency_tone = tone_freq[i];
		t.tones[i].amplitude_tone = -tone_ampl[i];
	}
	t.frame_duration = frame_dur;
	t.sequence_duration = sequence_dur;
	t.period_duration = period_dur;
	t.repetition = repetition;

	return_path.addr_id        = NULL;
	return_path.callback_func  = audio_callback;
	if (audio_tones_start(&t, return_path) == AUDIO_OK)
		return (ATI_CMPL);
	else
		return (ATI_FAIL);
}

/* AT@TSTOP - stop tones started with AT@TONE */
GLOBAL T_ATI_RSLT atAtTSTOP ( char *cl, UBYTE srcId )
{
	T_RV_RETURN return_path;

	return_path.addr_id        = NULL;
	return_path.callback_func  = audio_callback;
	if (audio_tones_stop(return_path) == AUDIO_OK)
		return (ATI_CMPL);
	else
		return (ATI_FAIL);
}

/* AT@VMP - play back a voice memo recording */
GLOBAL T_ATI_RSLT atAtVMP ( char *cl, UBYTE srcId )
{
	T_AUDIO_VM_PLAY_PARAMETER play_param;
	T_RV_RETURN return_path;

	cl = parse(cl, "S", (LONG)(sizeof(play_param.memo_name)),
		   play_param.memo_name);
	if (!cl || !play_param.memo_name[0])
		return (ATI_FAIL);

	return_path.addr_id        = NULL;
	return_path.callback_func  = audio_callback;
	if (audio_vm_play_start(&play_param, return_path) == AUDIO_OK)
		return (ATI_CMPL);
	else
		return (ATI_FAIL);
}

/* AT@VMPS - stop VM play started with AT@VMP */
GLOBAL T_ATI_RSLT atAtVMPS ( char *cl, UBYTE srcId )
{
	T_RV_RETURN return_path;

	return_path.addr_id        = NULL;
	return_path.callback_func  = audio_callback;
	if (audio_vm_play_stop(return_path) == AUDIO_OK)
		return (ATI_CMPL);
	else
		return (ATI_FAIL);
}

static const T_AUDIO_TONES_PARAMETER recorder_warning_tone = {
	0, 500, 1400, -5,
	0, 500, 0, 0,
	0, 500, 0, 0,
	500, 500, 15000, TONE_INFINITE
};

/* AT@VMR - record a voice memo */
GLOBAL T_ATI_RSLT atAtVMR ( char *cl, UBYTE srcId )
{
	T_AUDIO_VM_RECORD_PARAMETER record_param;
	int duration = 0, compression = 0;
	LONG mic_gain = 0x100, network_gain = 0x100;
	T_RV_RETURN return_path;

	cl = parse(cl, "Sddyy", (LONG)(sizeof(record_param.memo_name)),
		   record_param.memo_name, &duration, &compression,
		   &mic_gain, &network_gain);
	if (!cl || !record_param.memo_name[0] || !duration)
		return (ATI_FAIL);
	record_param.memo_duration = duration;
	record_param.compression_mode = compression;
	record_param.microphone_gain = mic_gain;
	record_param.network_gain = network_gain;

	return_path.addr_id        = NULL;
	return_path.callback_func  = audio_callback;
	if (audio_vm_record_start(&record_param,
				  (T_AUDIO_TONES_PARAMETER *)
					&recorder_warning_tone,
				  return_path) == AUDIO_OK)
		return (ATI_CMPL);
	else
		return (ATI_FAIL);
}

/* AT@VMRS - stop VM recording started with AT@VMR */
GLOBAL T_ATI_RSLT atAtVMRS ( char *cl, UBYTE srcId )
{
	T_RV_RETURN return_path;

	return_path.addr_id        = NULL;
	return_path.callback_func  = audio_callback;
	if (audio_vm_record_stop(return_path) == AUDIO_OK)
		return (ATI_CMPL);
	else
		return (ATI_FAIL);
}

#endif /* ATI_AUDIO_C */