Files
Main_MiSTer/audio.cpp
2022-10-31 23:05:20 +08:00

266 lines
5.7 KiB
C++

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/vt.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "hardware.h"
#include "user_io.h"
#include "spi.h"
#include "cfg.h"
#include "file_io.h"
#include "menu.h"
#include "audio.h"
static uint8_t vol_att = 0;
static uint8_t corevol_att = 0;
unsigned long vol_set_timeout = 0;
static int has_filter = 0;
static char filter_cfg_path[1024] = {};
static char filter_cfg[1024] = {};
static void setFilter()
{
fileTYPE f = {};
has_filter = spi_uio_cmd(UIO_SET_AFILTER);
if (!has_filter) return;
snprintf(filter_cfg_path, sizeof(filter_cfg_path), AFILTER_DIR"/%s", filter_cfg + 1);
if(filter_cfg[0]) printf("\nLoading audio filter: %s\n", filter_cfg_path);
if (filter_cfg[0] && FileExists(filter_cfg_path) && FileOpen(&f, filter_cfg_path))
{
char *buf = (char*)malloc(f.size + 1);
if (buf)
{
memset(buf, 0, f.size + 1);
int size;
if ((size = FileReadAdv(&f, buf, f.size)))
{
int line = 0;
spi_uio_cmd_cont(UIO_SET_AFILTER);
spi_w((uint8_t)get_core_volume());
char *end = buf + size;
char *pos = buf;
while (pos < end && line < 9)
{
char *st = pos;
while ((pos < end) && *pos && (*pos != 10)) pos++;
*pos = 0;
while (*st == ' ' || *st == '\t' || *st == 13) st++;
if (*st == '#' || *st == ';' || !*st) pos++;
else
{
if (line == 0)
{
printf("version: %s\n", st);
if (strncasecmp(st, "v1", 2)) break;
line++;
}
else if (line == 1 || line == 3 || line == 4 || line == 5)
{
int val = 0;
int n = sscanf(st, "%d", &val);
printf("got %d values: %d\n", n, val);
if (n == 1)
{
spi_w((uint16_t)val);
if (line == 1) spi_w((uint16_t)(val >> 16));
line++;
}
}
else if (line == 2)
{
double val = 0;
int n = sscanf(st, "%lg", &val);
printf("got %d values: %g\n", n, val);
if (n == 1)
{
int64_t coeff = 0x8000000000 * val;
printf(" -> converted to: %lld\n", coeff);
spi_w((uint16_t)coeff);
spi_w((uint16_t)(coeff >> 16));
spi_w((uint16_t)(coeff >> 32));
line++;
}
}
else
{
double val = 0;
int n = sscanf(st, "%lg", &val);
printf("got %d values: %g\n", n, val);
if (n == 1)
{
int32_t coeff = 0x200000 * val;
printf(" -> converted to: %d\n", coeff);
spi_w((uint16_t)coeff);
spi_w((uint16_t)(coeff >> 16));
line++;
}
}
}
}
DisableIO();
}
free(buf);
}
}
else
{
spi_uio_cmd8(UIO_SET_AFILTER, (uint8_t)get_core_volume());
}
}
void send_volume()
{
int vol = get_volume();
get_core_volume();
if (!has_filter)
{
if (!(vol_att & 0x10) && vol_att + corevol_att > 7) vol_att = 7 - corevol_att;
vol = vol_att + corevol_att;
}
spi_uio_cmd8(UIO_AUDVOL, vol);
}
int get_volume()
{
return vol_att & 0x17;
}
int get_core_volume()
{
corevol_att &= 7;
if (corevol_att > 6) corevol_att = 6;
return corevol_att;
}
void set_volume(int cmd)
{
vol_set_timeout = GetTimer(1000);
vol_att &= 0x17;
if ((cmd & 0xC0) == 0x80) vol_att = (vol_att & 0x7) | ((cmd & 1) << 4);
else if ((cmd & 0xC0) == 0x40) vol_att = (vol_att & 0x10) | (~cmd & 7);
else if (!cmd) vol_att ^= 0x10;
else if (vol_att & 0x10) vol_att &= 0xF;
else if (cmd < 0 && vol_att < 7) vol_att += 1;
else if (cmd > 0 && vol_att > 0) vol_att -= 1;
send_volume();
if (vol_att & 0x10)
{
Info("\x8d Mute", 1000);
}
else
{
char str[32];
memset(str, 0, sizeof(str));
sprintf(str, "\x8d ");
char *bar = str + strlen(str);
int vol = (audio_filter_en() < 0) ? get_core_volume() : 0;
memset(bar, 0x8C, 8 - vol);
memset(bar, 0x7f, 8 - vol - vol_att);
Info(str, 1000);
}
}
void set_core_volume(int cmd)
{
vol_set_timeout = GetTimer(1000);
corevol_att &= 7;
if (cmd < 0 && corevol_att < 6) corevol_att += 1;
if (cmd > 0 && corevol_att > 0) corevol_att -= 1;
if (has_filter) setFilter();
else send_volume();
}
void save_volume()
{
if (vol_set_timeout && CheckTimer(vol_set_timeout))
{
vol_set_timeout = 0;
FileSaveConfig("Volume.dat", &vol_att, 1);
static char cfg_name[128];
sprintf(cfg_name, "%s_volume.cfg", user_io_get_core_name());
FileSaveConfig(cfg_name, &corevol_att, 1);
}
}
void load_volume()
{
sprintf(filter_cfg_path, "%s_afilter.cfg", user_io_get_core_name());
if (!FileLoadConfig(filter_cfg_path, &filter_cfg, sizeof(filter_cfg) - 1) || filter_cfg[0] > 1)
{
memset(filter_cfg, 0, sizeof(filter_cfg));
if (cfg.afilter_default[0])
{
strcpy(filter_cfg + 1, cfg.afilter_default);
filter_cfg[0] = 1;
}
}
FileLoadConfig("Volume.dat", &vol_att, 1);
if (!is_menu())
{
static char cfg_name[128];
sprintf(cfg_name, "%s_volume.cfg", user_io_get_core_name());
FileLoadConfig(cfg_name, &corevol_att, 1);
}
get_volume();
get_core_volume();
setFilter();
send_volume();
}
int audio_filter_en()
{
return has_filter ? filter_cfg[0] : -1;
}
char* audio_get_filter(int only_name)
{
char *path = filter_cfg + 1;
if (only_name)
{
char *p = strrchr(path, '/');
if (p) return p + 1;
}
return path;
}
void audio_set_filter(const char *name)
{
strcpy(filter_cfg + 1, name);
sprintf(filter_cfg_path, "%s_afilter.cfg", user_io_get_core_name());
FileSaveConfig(filter_cfg_path, &filter_cfg, sizeof(filter_cfg));
setFilter();
}
void audio_set_filter_en(int n)
{
filter_cfg[0] = n ? 1 : 0;
sprintf(filter_cfg_path, "%s_afilter.cfg", user_io_get_core_name());
FileSaveConfig(filter_cfg_path, &filter_cfg, sizeof(filter_cfg));
setFilter();
}