/*
* EMU10k1 loader lib
* Copyright (c) 2003,2004 by Peter Zubaj
*
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "version.h"
#include "ld10k1.h"
#include "ld10k1_fnc.h"
#include "ld10k1_error.h"
#include "comm.h"
#include "liblo10k1.h"
#include "liblo10k1lf.h"
#define CREATER_MAJOR LD10K1_LIB_MAJOR
#define CREATER_MINOR LD10K1_LIB_MINOR
#define CREATER_SUBMINOR LD10K1_LIB_SUBMINOR
#define FILE_MAJOR 0
#define FILE_MINOR 1
#define FILE_SUBMINOR 0
#define READER_MAJOR 0
#define READER_MINOR 1
#define READER_SUBMINOR 7
#define LD10K1_FILE_SIGNATURE "LD10K1 NATIVE EFFECT FILE "
int liblo10k1lf_save_dsp_setup(liblo10k1_file_dsp_setup_t *c, FILE *file);
int liblo10k1lf_save_file_header(FILE *file, unsigned int ft);
int liblo10k1lf_save_file_info(FILE *file, liblo10k1_file_info_t *fi);
int liblo10k1lf_save_part(FILE *file, unsigned int part_type, unsigned int part_id, unsigned int part_length, void *data);
int liblo10k1lf_find_part(FILE *file, unsigned int part_type, unsigned int part_id, unsigned int part_length, liblo10k1_file_part_t *part);
int liblo10k1lf_find_part_il(FILE *file, unsigned int part_type, unsigned int part_id, unsigned int part_length, int il, liblo10k1_file_part_t *part);
int liblo10k1lf_save_dsp_config(liblo10k1_file_dsp_setup_t *c, char *file_name, liblo10k1_file_info_t *fi)
{
FILE *file = NULL;
int err;
file = fopen(file_name, "w");
if (!file)
return LD10K1_LF_ERR_OPEN;
if ((err = liblo10k1lf_save_file_header(file, LD10K1_FP_INFO_FILE_TYPE_DSP_SETUP)) < 0)
goto err;
if ((err = liblo10k1lf_save_file_info(file, fi)) < 0)
goto err;
if ((err = liblo10k1lf_save_dsp_setup(c, file)) < 0)
goto err;
fclose(file);
return 0;
err:
fclose(file);
return err;
}
int liblo10k1lf_save_part(FILE *file, unsigned int part_type, unsigned int part_id, unsigned int part_length, void *data)
{
liblo10k1_file_part_t part;
memset(&part, 0, sizeof(part));
part.part_type = part_type;
part.part_id = part_id;
part.part_length = part_length;
if (fwrite(&part, sizeof(liblo10k1_file_part_t), 1, file) != 1)
return LD10K1_LF_ERR_WRITE;
if (part_length > 0)
if (fwrite(data, part_length, 1, file) != 1)
return LD10K1_LF_ERR_WRITE;
return 0;
}
int liblo10k1lf_save_file_header(FILE *file, unsigned int ft)
{
liblo10k1_file_header_t fhdr;
liblo10k1_file_part_info_t file_info;
int err;
strcpy(fhdr.signature, LD10K1_FILE_SIGNATURE);
memset(fhdr.reserved, 0, sizeof(fhdr.reserved));
if (fwrite(&fhdr, sizeof(liblo10k1_file_header_t), 1, file) != 1)
return LD10K1_LF_ERR_WRITE;
memset(&file_info, 0, sizeof(file_info));
file_info.file_type = ft;
file_info.file_version_major = FILE_MAJOR;
file_info.file_version_minor = FILE_MINOR;
file_info.file_version_subminor = FILE_SUBMINOR; /* file version = 0.0.1 */
file_info.minimal_reader_version_major = READER_MAJOR;
file_info.minimal_reader_version_minor = READER_MINOR;
file_info.minimal_reader_version_subminor = READER_SUBMINOR; /* minimal reader version = 0.1.7 */
file_info.creater_version_major = CREATER_MAJOR;
file_info.creater_version_minor = CREATER_MINOR;
file_info.creater_version_subminor = CREATER_SUBMINOR; /* creater version = 0.1.7 */
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, LD10K1_FP_INFO, sizeof(file_info), &file_info)) < 0)
return err;
return 0;
}
int liblo10k1lf_save_string_info(FILE *file, int id, char *str)
{
int str_len;
int err;
if (str)
str_len = strlen(str) + 1;
else
str_len = 0;
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, id, str_len, str)) < 0)
return err;
return 0;
}
int liblo10k1lf_load_string_info(FILE *file, int id, char **str)
{
char *tmp;
int err;
liblo10k1_file_part_t part;
if ((err = liblo10k1lf_find_part_il(file, LD10K1_FP_TYPE_NORMAL, id, 0, 1, &part)) < 0)
return err;
tmp = NULL;
if (part.part_length > 0) {
tmp = (char *)malloc(part.part_length);
if (!tmp)
return LD10K1_ERR_NO_MEM;
if (fread(tmp, part.part_length, 1, file) != 1) {
free(tmp);
return LD10K1_LF_ERR_READ;
}
}
if (*str)
free(*str);
*str = tmp;
return 0;
}
int liblo10k1lf_save_file_info(FILE *file, liblo10k1_file_info_t *fi)
{
int err;
if ((err = liblo10k1lf_save_string_info(file, LD10K1_FP_FILE_INFO_NAME, fi->name)) < 0)
return err;
if ((err = liblo10k1lf_save_string_info(file, LD10K1_FP_FILE_INFO_DESC, fi->desc)) < 0)
return err;
if ((err = liblo10k1lf_save_string_info(file, LD10K1_FP_FILE_INFO_CREATER, fi->creater)) < 0)
return err;
if ((err = liblo10k1lf_save_string_info(file, LD10K1_FP_FILE_INFO_AUTHOR, fi->author)) < 0)
return err;
if ((err = liblo10k1lf_save_string_info(file, LD10K1_FP_FILE_INFO_COPYRIGHT, fi->copyright)) < 0)
return err;
if ((err = liblo10k1lf_save_string_info(file, LD10K1_FP_FILE_INFO_LICENCE, fi->license)) < 0)
return err;
return 0;
}
int liblo10k1lf_load_file_info(FILE *file, liblo10k1_file_info_t **fi)
{
int err;
liblo10k1_file_info_t *i = liblo10k1lf_file_info_alloc();
if (!i)
return LD10K1_ERR_NO_MEM;
if ((err = liblo10k1lf_load_string_info(file, LD10K1_FP_FILE_INFO_NAME, &(i->name))) < 0)
goto err;
if ((err = liblo10k1lf_load_string_info(file, LD10K1_FP_FILE_INFO_DESC, &(i->desc))) < 0)
goto err;
if ((err = liblo10k1lf_load_string_info(file, LD10K1_FP_FILE_INFO_CREATER, &(i->creater))) < 0)
goto err;
if ((err = liblo10k1lf_load_string_info(file, LD10K1_FP_FILE_INFO_AUTHOR, &(i->author))) < 0)
goto err;
if ((err = liblo10k1lf_load_string_info(file, LD10K1_FP_FILE_INFO_COPYRIGHT, &(i->copyright))) < 0)
goto err;
if ((err = liblo10k1lf_load_string_info(file, LD10K1_FP_FILE_INFO_LICENCE, &(i->license))) < 0)
goto err;
*fi = i;
return 0;
err:
if (i)
liblo10k1lf_file_info_free(i);
return err;
}
int liblo10k1lf_save_io(liblo10k1_get_io_t *ios, int count, int ptl, int pt, FILE *file)
{
int i, err;
/* io list start */
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, ptl, 0, NULL)) < 0)
return err;
for (i = 0; i < count; i++) {
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, pt, sizeof(liblo10k1_get_io_t), &(ios[i]))) < 0)
return err;
}
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, ptl, 0, NULL)) < 0)
return err;
return 0;
}
int liblo10k1lf_save_pio(liblo10k1_dsp_pio_t *ios, int count, int ptl, int pt, FILE *file)
{
int i, err;
/* io list start */
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, ptl, 0, NULL)) < 0)
return err;
for (i = 0; i < count; i++) {
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, pt, sizeof(liblo10k1_dsp_pio_t), &(ios[i]))) < 0)
return err;
}
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, ptl, 0, NULL)) < 0)
return err;
return 0;
}
int liblo10k1lf_save_cs(liblo10k1_dsp_cs_t *css, int count, int ptl, int pt, FILE *file)
{
int i, err;
/* io list start */
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, ptl, 0, NULL)) < 0)
return err;
for (i = 0; i < count; i++) {
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, pt, sizeof(liblo10k1_dsp_cs_t), &(css[i]))) < 0)
return err;
}
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, ptl, 0, NULL)) < 0)
return err;
return 0;
}
int liblo10k1lf_save_hw(liblo10k1_dsp_hw_t *hws, int count, FILE *file)
{
int i, err;
/* io list start */
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, LD10K1_FP_HW_LIST, 0, NULL)) < 0)
return err;
for (i = 0; i < count; i++) {
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, LD10K1_FP_HW, sizeof(liblo10k1_dsp_hw_t), &(hws[i]))) < 0)
return err;
}
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, LD10K1_FP_HW_LIST, 0, NULL)) < 0)
return err;
return 0;
}
int liblo10k1lf_save_tram(liblo10k1_dsp_tram_grp_t *trams, int count, FILE *file)
{
int i, err;
/* io list start */
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, LD10K1_FP_TRAM_LIST, 0, NULL)) < 0)
return err;
for (i = 0; i < count; i++) {
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, LD10K1_FP_TRAM, sizeof(liblo10k1_dsp_tram_grp_t), &(trams[i]))) < 0)
return err;
}
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, LD10K1_FP_TRAM_LIST, 0, NULL)) < 0)
return err;
return 0;
}
int liblo10k1lf_save_tram_acc(liblo10k1_dsp_tram_acc_t *tram_accs, int count, FILE *file)
{
int i, err;
/* io list start */
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, LD10K1_FP_TRAM_ACC_LIST, 0, NULL)) < 0)
return err;
for (i = 0; i < count; i++) {
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, LD10K1_FP_TRAM_ACC, sizeof(liblo10k1_dsp_tram_acc_t), &(tram_accs[i]))) < 0)
return err;
}
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, LD10K1_FP_TRAM_ACC_LIST, 0, NULL)) < 0)
return err;
return 0;
}
int liblo10k1lf_save_ctl(liblo10k1_dsp_ctl_t *ctls, int count, FILE *file)
{
int i, err;
/* io list start */
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, LD10K1_FP_CTL_LIST, 0, NULL)) < 0)
return err;
for (i = 0; i < count; i++) {
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, LD10K1_FP_CTL, sizeof(liblo10k1_dsp_ctl_t), &(ctls[i]))) < 0)
return err;
}
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, LD10K1_FP_CTL_LIST, 0, NULL)) < 0)
return err;
return 0;
}
int liblo10k1lf_save_instr(liblo10k1_dsp_instr_t *instrs, int count, FILE *file)
{
int i, err;
/* io list start */
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, LD10K1_FP_INSTR_LIST, 0, NULL)) < 0)
return err;
for (i = 0; i < count; i++) {
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, LD10K1_FP_INSTR, sizeof(liblo10k1_dsp_instr_t), &(instrs[i]))) < 0)
return err;
}
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, LD10K1_FP_INSTR_LIST, 0, NULL)) < 0)
return err;
return 0;
}
int liblo10k1lf_save_points(liblo10k1_point_info_t *points, int count, FILE *file)
{
int i, err;
/* io list start */
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, LD10K1_FP_POINT_LIST, 0, NULL)) < 0)
return err;
for (i = 0; i < count; i++) {
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, LD10K1_FP_POINT, sizeof(liblo10k1_point_info_t), &(points[i]))) < 0)
return err;
}
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, LD10K1_FP_POINT_LIST, 0, NULL)) < 0)
return err;
return 0;
}
int liblo10k1lf_save_patch(liblo10k1_dsp_patch_t *p, FILE *file)
{
int err;
liblo10k1_file_patch_info_t pinfo;
/* io list start */
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, LD10K1_FP_PATCH, 0, NULL)) < 0)
return err;
/* patch info */
strcpy(pinfo.patch_name, p->patch_name);
pinfo.in_count = p->in_count;
pinfo.out_count = p->out_count;
pinfo.const_count = p->const_count;
pinfo.sta_count = p->sta_count;
pinfo.dyn_count = p->dyn_count;
pinfo.hw_count = p->hw_count;
pinfo.tram_count = p->tram_count;
pinfo.tram_acc_count = p->tram_acc_count;
pinfo.ctl_count = p->ctl_count;
pinfo.instr_count = p->instr_count;
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, LD10K1_FP_PATCH_INFO, sizeof(liblo10k1_file_patch_info_t), &pinfo)) < 0)
return err;
/* pins */
if ((err = liblo10k1lf_save_pio(p->ins, p->in_count, LD10K1_FP_PIN_LIST, LD10K1_FP_PIO, file)) < 0)
return err;
/* pouts */
if ((err = liblo10k1lf_save_pio(p->outs, p->out_count, LD10K1_FP_POUT_LIST, LD10K1_FP_PIO, file)) < 0)
return err;
/* consts */
if ((err = liblo10k1lf_save_cs(p->consts, p->const_count, LD10K1_FP_CONST_LIST, LD10K1_FP_CS, file)) < 0)
return err;
/* stas */
if ((err = liblo10k1lf_save_cs(p->stas, p->sta_count, LD10K1_FP_STA_LIST, LD10K1_FP_CS, file)) < 0)
return err;
/* hws */
if ((err = liblo10k1lf_save_hw(p->hws, p->hw_count, file)) < 0)
return err;
/* trams */
if ((err = liblo10k1lf_save_tram(p->tram, p->tram_count, file)) < 0)
return err;
/* tram_accs */
if ((err = liblo10k1lf_save_tram_acc(p->tram_acc, p->tram_acc_count, file)) < 0)
return err;
/* ctls */
if ((err = liblo10k1lf_save_ctl(p->ctl, p->ctl_count, file)) < 0)
return err;
/* instrs */
if ((err = liblo10k1lf_save_instr(p->instr, p->instr_count, file)) < 0)
return err;
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, LD10K1_FP_PATCH, 0, NULL)) < 0)
return err;
return 0;
}
int liblo10k1lf_save_dsp_setup(liblo10k1_file_dsp_setup_t *c, FILE *file)
{
liblo10k1_file_part_dsp_setup_t setup;
int err;
int i;
setup.dsp_type = c->dsp_type;
setup.fx_count = c->fx_count;
setup.in_count = c->in_count;
setup.out_count = c->out_count;
setup.patch_count = c->patch_count;
setup.point_count = c->point_count;
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, LD10K1_FP_DSP_SETUP, sizeof(setup), &setup)) < 0)
return err;
/* save fx */
if ((err = liblo10k1lf_save_io(c->fxs, c->fx_count, LD10K1_FP_FX_LIST, LD10K1_FP_FX, file)) < 0)
return err;
/* save in */
if ((err = liblo10k1lf_save_io(c->ins, c->in_count, LD10K1_FP_IN_LIST, LD10K1_FP_IN, file)) < 0)
return err;
/* save out */
if ((err = liblo10k1lf_save_io(c->outs, c->out_count, LD10K1_FP_OUT_LIST, LD10K1_FP_OUT, file)) < 0)
return err;
/* save patches */
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, LD10K1_FP_PATCH_LIST, 0, NULL)) < 0)
return err;
for (i = 0; i < c->patch_count; i++) {
if ((err = liblo10k1lf_save_patch(c->patches[i], file)) < 0)
return err;
}
if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, LD10K1_FP_PATCH_LIST, 0, NULL)) < 0)
return err;
/* save points */
if ((err = liblo10k1lf_save_points(c->points, c->point_count, file)) < 0)
return err;
return 0;
}
liblo10k1_file_dsp_setup_t *liblo10k1lf_dsp_config_alloc()
{
liblo10k1_file_dsp_setup_t *tmp = (liblo10k1_file_dsp_setup_t *)malloc(sizeof(liblo10k1_file_dsp_setup_t));
memset(tmp, 0, sizeof(liblo10k1_file_dsp_setup_t));
return tmp;
}
void liblo10k1lf_dsp_config_free(liblo10k1_file_dsp_setup_t *c)
{
int i;
if (c->fxs)
free(c->fxs);
if (c->ins)
free(c->ins);
if (c->outs)
free(c->outs);
if (c->patches) {
for (i = 0; i < c->patch_count; i++) {
if (c->patches[i])
liblo10k1_patch_free(c->patches[i]);
}
free(c->patches);
}
if (c->points)
free(c->points);
}
int liblo10k1lf_dsp_config_set_fx_count(liblo10k1_file_dsp_setup_t *c, int count)
{
liblo10k1_get_io_t *tmp = NULL;
if (count > 0) {
tmp = (liblo10k1_get_io_t *)malloc(sizeof(liblo10k1_get_io_t) * count);
if (!tmp)
return LD10K1_ERR_NO_MEM;
}
if (c->fxs)
free(c->fxs);
c->fx_count = count;
c->fxs = tmp;
return 0;
}
int liblo10k1lf_dsp_config_set_in_count(liblo10k1_file_dsp_setup_t *c, int count)
{
liblo10k1_get_io_t *tmp = NULL;
if (count > 0) {
tmp = (liblo10k1_get_io_t *)malloc(sizeof(liblo10k1_get_io_t) * count);
if (!tmp)
return LD10K1_ERR_NO_MEM;
}
if (c->ins)
free(c->ins);
c->in_count = count;
c->ins = tmp;
return 0;
}
int liblo10k1lf_dsp_config_set_out_count(liblo10k1_file_dsp_setup_t *c, int count)
{
liblo10k1_get_io_t *tmp = NULL;
if (count > 0) {
tmp = (liblo10k1_get_io_t *)malloc(sizeof(liblo10k1_get_io_t) * count);
if (!tmp)
return LD10K1_ERR_NO_MEM;
}
if (c->outs)
free(c->outs);
c->out_count = count;
c->outs = tmp;
return 0;
}
int liblo10k1lf_dsp_config_set_patch_count(liblo10k1_file_dsp_setup_t *c, int count)
{
int i;
/* alloc patches list */
liblo10k1_dsp_patch_t **tmp = NULL;
if (count > 0) {
tmp = (liblo10k1_dsp_patch_t **)malloc(sizeof(liblo10k1_dsp_patch_t *) * count);
if (!tmp)
return LD10K1_ERR_NO_MEM;
memset(tmp, 0, sizeof(liblo10k1_dsp_patch_t *) * count);
}
if (c->patches) {
for (i = 0; i < c->patch_count; i++) {
if (c->patches[i])
liblo10k1_patch_free(c->patches[i]);
}
free(c->patches);
}
c->patch_count = count;
c->patches = tmp;
return 0;
}
int liblo10k1lf_dsp_config_set_point_count(liblo10k1_file_dsp_setup_t *c, int count)
{
liblo10k1_point_info_t *tmp = NULL;
if (count > 0) {
tmp = (liblo10k1_point_info_t *)malloc(sizeof(liblo10k1_point_info_t) * count);
if (!tmp)
return LD10K1_ERR_NO_MEM;
memset(tmp, 0, sizeof(liblo10k1_point_info_t) * count);
}
if (c->points)
free(c->points);
c->point_count = count;
c->points = tmp;
return 0;
}
int liblo10k1lf_get_dsp_config(liblo10k1_connection_t *conn, liblo10k1_file_dsp_setup_t **setup)
{
liblo10k1_dsp_info_t info;
int err;
int i, j, k;
liblo10k1_file_dsp_setup_t *s;
liblo10k1_patches_info_t *plist;
int pcount;
int tmp;
int *points;
plist = NULL;
points = NULL;
s = liblo10k1lf_dsp_config_alloc();
if (!s)
return LD10K1_ERR_NO_MEM;
/* get dsp type */
if ((err = liblo10k1_get_dsp_info(conn, &info)) < 0)
return err;
s->dsp_type = LD10K1_FP_INFO_DSP_TYPE_EMU10K1;
if (info.chip_type == CHIP_LIVE)
s->dsp_type = LD10K1_FP_INFO_DSP_TYPE_EMU10K1;
else if (info.chip_type == CHIP_AUDIGY)
s->dsp_type = LD10K1_FP_INFO_DSP_TYPE_EMU10K2;
/* now get everything what is needed */
if ((err = liblo10k1_get_fx_count(conn, &tmp)) < 0)
goto err;
if ((err = liblo10k1lf_dsp_config_set_fx_count(s, tmp)) < 0)
goto err;
for (i = 0; i < s->fx_count; i++) {
if ((err = liblo10k1_get_fx(conn, i, &(s->fxs[i]))) < 0)
goto err;
}
if ((err = liblo10k1_get_in_count(conn, &tmp)) < 0)
goto err;
if ((err = liblo10k1lf_dsp_config_set_in_count(s, tmp)) < 0)
goto err;
for (i = 0; i < s->in_count; i++) {
if ((err = liblo10k1_get_in(conn, i, &(s->ins[i]))) < 0)
goto err;
}
if ((err = liblo10k1_get_out_count(conn, &tmp)) < 0)
goto err;
if ((err = liblo10k1lf_dsp_config_set_out_count(s, tmp)) < 0)
goto err;
for (i = 0; i < s->out_count; i++) {
if ((err = liblo10k1_get_out(conn, i, &(s->outs[i]))) < 0)
goto err;
}
if ((err = liblo10k1_get_patches_info(conn, &plist, &pcount)) < 0)
goto err;
/* alloc patches list */
if ((err = liblo10k1lf_dsp_config_set_patch_count(s, pcount)) < 0)
goto err;
for (i = 0; i < s->patch_count; i++) {
if ((err = liblo10k1_patch_get(conn, plist[i].patch_num, &(s->patches[i]))) < 0)
goto err;
}
if ((err = liblo10k1_get_points_info(conn, &points, &pcount)) < 0)
goto err;
if ((err = liblo10k1lf_dsp_config_set_point_count(s, pcount)) < 0)
goto err;
for (i = 0; i < s->point_count; i++) {
if ((err = liblo10k1_get_point_info(conn, points[i], &(s->points[i]))) < 0)
goto err;
/* id to patch index */
for (j = 0; j < s->points[i].conn_count;j++) {
if (s->points[i].patch[j] >= 0) {
for (k = 0; k < s->patch_count; k++) {
if (plist[k].id == s->points[i].patch[j]) {
s->points[i].patch[j] = k;
break;
}
}
if (s->points[i].patch[j] != k) {
err = LD10K1_ERR_UNKNOWN_PATCH_NUM;
goto err;
}
}
}
}
free(plist);
free(points);
*setup = s;
return 0;
err:
if (plist)
free(plist);
if (points)
free(points);
liblo10k1lf_dsp_config_free(s);
return err;
}
int liblo10k1lf_put_dsp_config(liblo10k1_connection_t *conn, liblo10k1_file_dsp_setup_t *setup)
{
int err;
int i, j;
int loaded_id;
int loaded;
int *trans_nums;
int tin_type, tout_type;
int tin, tout;
int tpin, tpout;
int pnum;
tin_type = 0;
tout_type = 0;
tin = 0;
tout = 0;
tpin = 0;
tpout = 0;
/* first initialize dsp */
if ((err = liblo10k1_dsp_init(conn)) < 0)
return err;
for (i = 0; i < setup->fx_count; i++) {
if ((err = liblo10k1_rename_fx(conn, i, setup->fxs[i].name)) < 0)
return err;
}
for (i = 0; i < setup->in_count; i++) {
if ((err = liblo10k1_rename_in(conn, i, setup->ins[i].name)) < 0)
return err;
}
for (i = 0; i < setup->out_count; i++) {
if ((err = liblo10k1_rename_out(conn, i, setup->outs[i].name)) < 0)
return err;
}
if (setup->patch_count <= 0)
return 0;
trans_nums = (int *)malloc(sizeof(int) * setup->patch_count);
if (!trans_nums)
return LD10K1_ERR_NO_MEM;
memset(trans_nums, 0, sizeof(int) * setup->patch_count);
/* load all patches - remember ids */
for (i = 0; i < setup->patch_count; i++) {
if ((err = liblo10k1_patch_load(conn, setup->patches[i], -1, &loaded, &loaded_id)) < 0)
goto err;
trans_nums[i] = loaded;
}
/* connect all connections */
for (i = 0; i < setup->point_count; i++) {
if (setup->points[i].type == CON_IO_NORMAL) {
/* find first pin */
for (j = 0; j < setup->points[i].conn_count;j++)
if (!setup->points[i].io_type[j]) {
tin_type = CON_IO_PIN;
tin = setup->points[i].io[j];
tpin = setup->points[i].patch[j];
if (tpin >= 0)
tpin = trans_nums[tpin];
break;
}
/* find first pout */
for (j = 0; j < setup->points[i].conn_count;j++)
if (setup->points[i].io_type[j]) {
tout_type = CON_IO_POUT;
tout = setup->points[i].io[j];
tpout = setup->points[i].patch[j];
if (tpout >= 0)
tpout = trans_nums[tpout];
break;
}
for (j = 0; j < setup->points[i].conn_count; j++) {
pnum = setup->points[i].patch[j];
if (pnum >= 0)
pnum = trans_nums[pnum];
if (!setup->points[i].io_type[j]) {
if ((err = liblo10k1_con_add(conn, j == 0 ? 0 : setup->points[i].multi,
setup->points[i].simple, CON_IO_PIN, pnum, setup->points[i].io[j],
tout_type, tpout, tout, NULL)) < 0)
goto err;
} else {
if ((err = liblo10k1_con_add(conn, j == 0 ? 0 : setup->points[i].multi,
setup->points[i].simple, CON_IO_POUT, pnum, setup->points[i].io[j],
tin_type, tpin, tin, NULL)) < 0)
goto err;
}
}
} else {
tin_type = tout_type = setup->points[i].type;
tin = tout = setup->points[i].io_idx;
tpin = tpout = -1;
for (j = 0; j < setup->points[i].conn_count; j++) {
pnum = setup->points[i].patch[j];
if (pnum >= 0)
pnum = trans_nums[pnum];
if ((err = liblo10k1_con_add(conn, j == 0 ? 0 : setup->points[i].multi,
setup->points[i].simple, setup->points[i].io_type[j] ? CON_IO_POUT : CON_IO_PIN, pnum, setup->points[i].io[j],
tin_type, tpin, tin, NULL)) < 0)
goto err;
}
}
}
return 0;
err:
if (trans_nums)
free(trans_nums);
return err;
}
int liblo10k1lf_skip_part(FILE *file, liblo10k1_file_part_t *part)
{
char tmp_char;
int i;
int err;
int found_end_part = 0;
if (part->part_type == LD10K1_FP_TYPE_NORMAL) {
/* read all data */
for (i = 0; i < part->part_length; i++)
if (fread(&tmp_char, 1, 1, file) != 1)
return LD10K1_LF_ERR_READ;
} else if (part->part_type == LD10K1_FP_TYPE_END) {
return 0;
} else {
while (!found_end_part) {
/* read next part */
if (fread(part, sizeof(liblo10k1_file_part_t), 1, file) != 1)
return LD10K1_LF_ERR_READ;
/* check type & id */
if (part->part_type == LD10K1_FP_TYPE_END)
found_end_part = 1;
else {
if ((err = liblo10k1lf_skip_part(file, part)) < 0)
return err;
}
}
}
return 0;
}
int liblo10k1lf_find_part_il(FILE *file, unsigned int part_type, unsigned int part_id, unsigned int part_length, int il, liblo10k1_file_part_t *part)
{
int err;
while (1) {
if (fread(part, sizeof(liblo10k1_file_part_t), 1, file) != 1)
return LD10K1_LF_ERR_READ;
/* check type & id */
if (part->part_type == part_type && part->part_id == part_id) {
if (part->part_type == LD10K1_FP_TYPE_NORMAL) {
if (il || part->part_length == part_length)
return 0;
else
return LD10K1_LF_ERR_PART_SIZE;
} else {
if (part->part_length != 0)
return LD10K1_LF_ERR_PART_SIZE;
else
return 0;
}
} else {
if ((err = liblo10k1lf_skip_part(file, part)) < 0)
return err;
}
}
}
int liblo10k1lf_find_part(FILE *file, unsigned int part_type, unsigned int part_id, unsigned int part_length, liblo10k1_file_part_t *part)
{
return liblo10k1lf_find_part_il(file, part_type, part_id, part_length, 0, part);
}
int liblo10k1lf_find_part_ws(FILE *file, unsigned int part_id, unsigned int part_length, liblo10k1_file_part_t *part)
{
return liblo10k1lf_find_part(file, LD10K1_FP_TYPE_NORMAL, part_id, part_length, part);
}
int liblo10k1lf_find_part_start(FILE *file, unsigned int part_id)
{
liblo10k1_file_part_t part;
return liblo10k1lf_find_part(file, LD10K1_FP_TYPE_START, part_id, 0, &part);
}
int liblo10k1lf_find_part_end(FILE *file, unsigned int part_id)
{
liblo10k1_file_part_t part;
return liblo10k1lf_find_part(file, LD10K1_FP_TYPE_END, part_id, 0, &part);
}
int liblo10k1lf_find_load_part_ws(FILE *file, unsigned int part_id, unsigned int part_length, void *where)
{
int err;
liblo10k1_file_part_t part;
if ((err = liblo10k1lf_find_part_ws(file, part_id, part_length, &part)) < 0)
return err;
if (fread(where, part_length, 1, file) != 1)
return LD10K1_LF_ERR_READ;
return 0;
}
int liblo10k1lf_can_load_file(FILE *file, unsigned int ft)
{
liblo10k1_file_header_t fhdr;
liblo10k1_file_part_info_t file_info;
int err;
if (fread(&fhdr, sizeof(liblo10k1_file_header_t), 1, file) != 1)
return LD10K1_LF_ERR_READ;
/* check signature */
if (strcmp(fhdr.signature, LD10K1_FILE_SIGNATURE) != 0)
return LD10K1_LF_ERR_SIGNATURE;
/* now load file info part & check version */
if ((err = liblo10k1lf_find_load_part_ws(file, LD10K1_FP_INFO, sizeof(file_info), &file_info)) < 0)
return err;
if (file_info.minimal_reader_version_major > CREATER_MAJOR)
return LD10K1_LF_ERR_VERSION;
if (file_info.minimal_reader_version_major == CREATER_MAJOR &&
file_info.minimal_reader_version_minor > CREATER_MINOR)
return LD10K1_LF_ERR_VERSION;
if (file_info.minimal_reader_version_major == CREATER_MAJOR &&
file_info.minimal_reader_version_minor == CREATER_MINOR &&
file_info.minimal_reader_version_subminor > CREATER_SUBMINOR)
return LD10K1_LF_ERR_VERSION;
/* check file type */
if (file_info.file_type != ft)
return LD10K1_LF_ERR_FILE_TYPE;
return 0;
}
int liblo10k1lf_load_io(liblo10k1_get_io_t *ios, int count, int ptl, int pt, FILE *file)
{
int i, err;
/* io list start */
if ((err = liblo10k1lf_find_part_start(file, ptl)) < 0)
return err;
for (i = 0; i < count; i++) {
if ((err = liblo10k1lf_find_load_part_ws(file, pt, sizeof(liblo10k1_get_io_t), &(ios[i]))) < 0)
return err;
}
if ((err = liblo10k1lf_find_part_end(file, ptl)) < 0)
return err;
return 0;
}
int liblo10k1lf_load_points(liblo10k1_point_info_t *points, int count, FILE *file)
{
int i, err;
/* io list start */
if ((err = liblo10k1lf_find_part_start(file, LD10K1_FP_POINT_LIST)) < 0)
return err;
for (i = 0; i < count; i++) {
if ((err = liblo10k1lf_find_load_part_ws(file, LD10K1_FP_POINT, sizeof(liblo10k1_point_info_t), &(points[i]))) < 0)
return err;
}
if ((err = liblo10k1lf_find_part_end(file, LD10K1_FP_POINT_LIST)) < 0)
return err;
return 0;
}
int liblo10k1lf_load_pio(liblo10k1_dsp_pio_t *ios, int count, int ptl, int pt, FILE *file)
{
int i, err;
/* io list start */
if ((err = liblo10k1lf_find_part_start(file, ptl)) < 0)
return err;
for (i = 0; i < count; i++) {
if ((err = liblo10k1lf_find_load_part_ws(file, pt, sizeof(liblo10k1_dsp_pio_t), &(ios[i]))) < 0)
return err;
}
if ((err = liblo10k1lf_find_part_end(file, ptl)) < 0)
return err;
return 0;
}
int liblo10k1lf_load_cs(liblo10k1_dsp_cs_t *css, int count, int ptl, int pt, FILE *file)
{
int i, err;
/* io list start */
if ((err = liblo10k1lf_find_part_start(file, ptl)) < 0)
return err;
for (i = 0; i < count; i++) {
if ((err = liblo10k1lf_find_load_part_ws(file, pt, sizeof(liblo10k1_dsp_cs_t), &(css[i]))) < 0)
return err;
}
if ((err = liblo10k1lf_find_part_end(file, ptl)) < 0)
return err;
return 0;
}
int liblo10k1lf_load_hw(liblo10k1_dsp_hw_t *hws, int count, FILE *file)
{
int i, err;
/* io list start */
if ((err = liblo10k1lf_find_part_start(file, LD10K1_FP_HW_LIST)) < 0)
return err;
for (i = 0; i < count; i++) {
if ((err = liblo10k1lf_find_load_part_ws(file, LD10K1_FP_HW, sizeof(liblo10k1_dsp_hw_t), &(hws[i]))) < 0)
return err;
}
if ((err = liblo10k1lf_find_part_end(file, LD10K1_FP_HW_LIST)) < 0)
return err;
return 0;
}
int liblo10k1lf_load_tram(liblo10k1_dsp_tram_grp_t *trams, int count, FILE *file)
{
int i, err;
/* io list start */
if ((err = liblo10k1lf_find_part_start(file, LD10K1_FP_TRAM_LIST)) < 0)
return err;
for (i = 0; i < count; i++) {
if ((err = liblo10k1lf_find_load_part_ws(file, LD10K1_FP_TRAM, sizeof(liblo10k1_dsp_tram_grp_t), &(trams[i]))) < 0)
return err;
}
if ((err = liblo10k1lf_find_part_end(file, LD10K1_FP_TRAM_LIST)) < 0)
return err;
return 0;
}
int liblo10k1lf_load_tram_acc(liblo10k1_dsp_tram_acc_t *tram_accs, int count, FILE *file)
{
int i, err;
/* io list start */
if ((err = liblo10k1lf_find_part_start(file, LD10K1_FP_TRAM_ACC_LIST)) < 0)
return err;
for (i = 0; i < count; i++) {
if ((err = liblo10k1lf_find_load_part_ws(file, LD10K1_FP_TRAM_ACC, sizeof(liblo10k1_dsp_tram_acc_t), &(tram_accs[i]))) < 0)
return err;
}
if ((err = liblo10k1lf_find_part_end(file, LD10K1_FP_TRAM_ACC_LIST)) < 0)
return err;
return 0;
}
int liblo10k1lf_load_ctl(liblo10k1_dsp_ctl_t *ctls, int count, FILE *file)
{
int i, err;
/* io list start */
if ((err = liblo10k1lf_find_part_start(file, LD10K1_FP_CTL_LIST)) < 0)
return err;
for (i = 0; i < count; i++) {
if ((err = liblo10k1lf_find_load_part_ws(file, LD10K1_FP_CTL, sizeof(liblo10k1_dsp_ctl_t), &(ctls[i]))) < 0)
return err;
}
if ((err = liblo10k1lf_find_part_end(file, LD10K1_FP_CTL_LIST)) < 0)
return err;
return 0;
}
int liblo10k1lf_load_instr(liblo10k1_dsp_instr_t *instrs, int count, FILE *file)
{
int i, err;
/* io list start */
if ((err = liblo10k1lf_find_part_start(file, LD10K1_FP_INSTR_LIST)) < 0)
return err;
for (i = 0; i < count; i++) {
if ((err = liblo10k1lf_find_load_part_ws(file, LD10K1_FP_INSTR, sizeof(liblo10k1_dsp_instr_t), &(instrs[i]))) < 0)
return err;
}
if ((err = liblo10k1lf_find_part_end(file, LD10K1_FP_INSTR_LIST)) < 0)
return err;
return 0;
}
int liblo10k1lf_load_patch(liblo10k1_dsp_patch_t **p, FILE *file)
{
int err;
liblo10k1_file_patch_info_t pinfo;
liblo10k1_dsp_patch_t *patch = NULL;
/* io list start */
if ((err = liblo10k1lf_find_part_start(file, LD10K1_FP_PATCH)) < 0)
return err;
/* patch info */
if ((err = liblo10k1lf_find_load_part_ws(file, LD10K1_FP_PATCH_INFO, sizeof(liblo10k1_file_patch_info_t), &pinfo)) < 0)
return err;
patch = liblo10k1_patch_alloc(pinfo.in_count, pinfo.out_count, pinfo.const_count, pinfo.sta_count, pinfo.dyn_count,
pinfo.hw_count, pinfo.tram_count, pinfo.tram_acc_count, pinfo.ctl_count, pinfo.instr_count);
if (!patch) {
err = LD10K1_ERR_NO_MEM;
goto err;
}
strcpy(patch->patch_name, pinfo.patch_name);
/* pins */
if ((err = liblo10k1lf_load_pio(patch->ins, patch->in_count, LD10K1_FP_PIN_LIST, LD10K1_FP_PIO, file)) < 0)
return err;
/* pouts */
if ((err = liblo10k1lf_load_pio(patch->outs, patch->out_count, LD10K1_FP_POUT_LIST, LD10K1_FP_PIO, file)) < 0)
return err;
/* consts */
if ((err = liblo10k1lf_load_cs(patch->consts, patch->const_count, LD10K1_FP_CONST_LIST, LD10K1_FP_CS, file)) < 0)
return err;
/* stas */
if ((err = liblo10k1lf_load_cs(patch->stas, patch->sta_count, LD10K1_FP_STA_LIST, LD10K1_FP_CS, file)) < 0)
return err;
/* hws */
if ((err = liblo10k1lf_load_hw(patch->hws, patch->hw_count, file)) < 0)
return err;
/* trams */
if ((err = liblo10k1lf_load_tram(patch->tram, patch->tram_count, file)) < 0)
return err;
/* tram_accs */
if ((err = liblo10k1lf_load_tram_acc(patch->tram_acc, patch->tram_acc_count, file)) < 0)
return err;
/* ctls */
if ((err = liblo10k1lf_load_ctl(patch->ctl, patch->ctl_count, file)) < 0)
return err;
/* instrs */
if ((err = liblo10k1lf_load_instr(patch->instr, patch->instr_count, file)) < 0)
return err;
if ((err = liblo10k1lf_find_part_end(file, LD10K1_FP_PATCH)) < 0)
return err;
*p = patch;
return 0;
err:
if (patch)
liblo10k1_patch_free(patch);
return err;
}
int liblo10k1lf_load_dsp_setup(liblo10k1_file_dsp_setup_t **c, FILE *file)
{
liblo10k1_file_part_dsp_setup_t setup;
int err;
int i;
liblo10k1_file_dsp_setup_t *cfg;
if ((err = liblo10k1lf_find_load_part_ws(file, LD10K1_FP_DSP_SETUP, sizeof(setup), &setup)) < 0)
return err;
cfg = liblo10k1lf_dsp_config_alloc();
cfg->dsp_type = setup.dsp_type;
/* alloc space */
if ((err = liblo10k1lf_dsp_config_set_fx_count(cfg, setup.fx_count)) < 0)
goto err;
if ((err = liblo10k1lf_dsp_config_set_in_count(cfg, setup.in_count)) < 0)
goto err;
if ((err = liblo10k1lf_dsp_config_set_out_count(cfg, setup.out_count)) < 0)
goto err;
if ((err = liblo10k1lf_dsp_config_set_patch_count(cfg, setup.patch_count)) < 0)
goto err;
if ((err = liblo10k1lf_dsp_config_set_point_count(cfg, setup.point_count)) < 0)
goto err;
/* load fx */
if ((err = liblo10k1lf_load_io(cfg->fxs, cfg->fx_count, LD10K1_FP_FX_LIST, LD10K1_FP_FX, file)) < 0)
return err;
/* load in */
if ((err = liblo10k1lf_load_io(cfg->ins, cfg->in_count, LD10K1_FP_IN_LIST, LD10K1_FP_IN, file)) < 0)
return err;
/* load out */
if ((err = liblo10k1lf_load_io(cfg->outs, cfg->out_count, LD10K1_FP_OUT_LIST, LD10K1_FP_OUT, file)) < 0)
return err;
/* load patches */
if ((err = liblo10k1lf_find_part_start(file, LD10K1_FP_PATCH_LIST)) < 0)
return err;
for (i = 0; i < cfg->patch_count; i++) {
if ((err = liblo10k1lf_load_patch(&(cfg->patches[i]), file)) < 0)
return err;
}
if ((err = liblo10k1lf_find_part_end(file, LD10K1_FP_PATCH_LIST)) < 0)
return err;
/* load points */
if ((err = liblo10k1lf_load_points(cfg->points, cfg->point_count, file)) < 0)
return err;
*c = cfg;
return 0;
err:
if (cfg)
liblo10k1lf_dsp_config_free(cfg);
return err;
}
int liblo10k1lf_load_dsp_config(liblo10k1_file_dsp_setup_t **c, char *file_name, liblo10k1_file_info_t **fi)
{
FILE *file = NULL;
int err;
liblo10k1_file_info_t *i = NULL;
file = fopen(file_name, "r");
if (!file)
return LD10K1_LF_ERR_OPEN;
if ((err = liblo10k1lf_can_load_file(file, LD10K1_FP_INFO_FILE_TYPE_DSP_SETUP)) < 0)
goto err;
if ((err = liblo10k1lf_load_file_info(file, &i)) < 0)
goto err;
if ((err = liblo10k1lf_load_dsp_setup(c, file)) < 0)
goto err;
*fi = i;
fclose(file);
return 0;
err:
if (i)
liblo10k1lf_file_info_free(i);
fclose(file);
return err;
}
liblo10k1_file_info_t *liblo10k1lf_file_info_alloc()
{
liblo10k1_file_info_t *tmp = (liblo10k1_file_info_t *)malloc(sizeof(liblo10k1_file_info_t));
if (tmp)
memset(tmp, 0, sizeof(liblo10k1_file_info_t));
return tmp;
}
void liblo10k1lf_file_info_free(liblo10k1_file_info_t *fi)
{
if (fi->name)
free(fi->name);
if (fi->desc)
free(fi->desc);
if (fi->creater)
free(fi->creater);
if (fi->author)
free(fi->author);
if (fi->copyright)
free(fi->copyright);
if (fi->license)
free(fi->license);
}
int liblo10k1lf_save_dsp_patch(liblo10k1_dsp_patch_t *p, char *file_name, liblo10k1_file_info_t *fi)
{
FILE *file = NULL;
int err;
file = fopen(file_name, "w");
if (!file)
return LD10K1_LF_ERR_OPEN;
if ((err = liblo10k1lf_save_file_header(file, LD10K1_FP_INFO_FILE_TYPE_PATCH)) < 0)
goto err;
if ((err = liblo10k1lf_save_file_info(file, fi)) < 0)
goto err;
if ((err = liblo10k1lf_save_patch(p, file)) < 0)
goto err;
fclose(file);
return 0;
err:
fclose(file);
return err;
}
int liblo10k1lf_load_dsp_patch(liblo10k1_dsp_patch_t **p, char *file_name, liblo10k1_file_info_t **fi)
{
FILE *file = NULL;
int err;
liblo10k1_file_info_t *i = NULL;
file = fopen(file_name, "r");
if (!file)
return LD10K1_LF_ERR_OPEN;
if ((err = liblo10k1lf_can_load_file(file, LD10K1_FP_INFO_FILE_TYPE_PATCH)) < 0)
goto err;
if ((err = liblo10k1lf_load_file_info(file, &i)) < 0)
goto err;
if ((err = liblo10k1lf_load_patch(p, file)) < 0)
goto err;
*fi = i;
fclose(file);
return 0;
err:
if (i)
liblo10k1lf_file_info_free(i);
fclose(file);
return err;
}