[alsa-devel] [PATCH 0/3] hdspmixer: Fix preset loading code
Hi!
This small series of patches now detects three different file formats for hdspmixer's preset file:
- pre 1.0.24 - 1.0.24 and 1.0.24.1 - new format with magic header
This should catch almost all mix files available in the wild unless those files were written with an unreleased development version of hdspmixer in the last few weeks.
Cheers
Adrian Knoth (3): hdspmixer: Fix read/write from/to preset files on MADI-like cards hdspmixer: Handle channel count in old (v1.0.23) preset file format hdspmixer: Handle preset files used in 1.0.24 and 1.0.24.1
hdspmixer/src/HDSPMixerWindow.cxx | 60 ++++++++++++++++++++++++++++++------ 1 files changed, 50 insertions(+), 10 deletions(-)
The old hdspmixer (prior to e24e56795ea57e3dd7da45063ab71f04e231192d, that is pre-1.0.24) has used the hard-coded value "14" for reading/storing 14 ints from/to preset files, however, it's actually HDSP_MAX_DEST that should be used.
HDSP_MAX_DEST was bumped from 14 to 32 to allow for MADI cards (32 stereo pairs equal 64 output channels on MADI cards)
Signed-off-by: Adrian Knoth adi@drcomp.erfurt.thur.de
diff --git a/hdspmixer/src/HDSPMixerWindow.cxx b/hdspmixer/src/HDSPMixerWindow.cxx index 75fbc4f..d6d28e3 100644 --- a/hdspmixer/src/HDSPMixerWindow.cxx +++ b/hdspmixer/src/HDSPMixerWindow.cxx @@ -337,7 +337,25 @@ static int handler_cb(int event)
void HDSPMixerWindow::save() { + const int pan_array_size = + sizeof(inputs->strips[0]->data[0][0][0]->pan_pos) / + sizeof(inputs->strips[0]->data[0][0][0]->pan_pos[0]); + /* MixerStripData defines pan_pos[HDSP_MAX_DEST], but just in case this + * will ever change, let's detect it early and fail safely instead of + * reading/writing garbage from/to preset files + */ + assert (HDSP_MAX_DEST == pan_array_size); + + /* also make sure that fader_pos[] has the same size as pan_pos. This comes + * naturally, but just to be sure. + */ + assert (pan_array_size == + sizeof(inputs->strips[0]->data[0][0][0]->fader_pos) / + sizeof(inputs->strips[0]->data[0][0][0]->fader_pos[0])); + + FILE *file; + if ((file = fopen(file_name, "w")) == NULL) { fl_alert("Error opening file %s for saving", file_name); } @@ -356,17 +374,17 @@ void HDSPMixerWindow::save() for (int preset = 0; preset < 8; ++preset) { for (int channel = 0; channel < HDSP_MAX_CHANNELS; ++channel) { /* inputs pans and volumes */ - if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->pan_pos[0]), sizeof(int), 14, file) != 14) { + if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->pan_pos[0]), sizeof(int), pan_array_size, file) != pan_array_size) { goto save_error; } - if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->fader_pos[0]), sizeof(int), 14, file) != 14) { + if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->fader_pos[0]), sizeof(int), pan_array_size, file) != pan_array_size) { goto save_error; } /* playbacks pans and volumes */ - if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->pan_pos[0]), sizeof(int), 14, file) != 14) { + if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->pan_pos[0]), sizeof(int), pan_array_size, file) != pan_array_size) { goto save_error; } - if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->fader_pos[0]), sizeof(int), 14, file) != 14) { + if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->fader_pos[0]), sizeof(int), pan_array_size, file) != pan_array_size) { goto save_error; } /* inputs mute/solo/dest */ @@ -469,12 +487,15 @@ void HDSPMixerWindow::load() /* check for new ondisk format */ char buffer[sizeof(header)]; bool ondisk_v1 = false; + int pan_array_size = 14; /* old (pre 1.0.24) HDSP_MAX_DEST */ + if (fread(&buffer, sizeof(char), sizeof(buffer), file) != sizeof(buffer)) { goto load_error; } if (0 == strncmp(buffer, header, sizeof(buffer))) { /* new ondisk format found */ ondisk_v1 = true; + pan_array_size = HDSP_MAX_DEST; } else { /* old format, rewind to the start and simply read all data */ rewind(file); @@ -485,17 +506,17 @@ void HDSPMixerWindow::load() for (int preset = 0; preset < 8; ++preset) { for (int channel = 0; channel < HDSP_MAX_CHANNELS; ++channel) { /* inputs pans and volumes */ - if (fread((void *)&(inputs->strips[channel]->data[card][speed][preset]->pan_pos[0]), sizeof(int), 14, file) != 14) { + if (fread((void *)&(inputs->strips[channel]->data[card][speed][preset]->pan_pos[0]), sizeof(int), pan_array_size, file) != pan_array_size) { goto load_error; } - if (fread((void *)&(inputs->strips[channel]->data[card][speed][preset]->fader_pos[0]), sizeof(int), 14, file) != 14) { + if (fread((void *)&(inputs->strips[channel]->data[card][speed][preset]->fader_pos[0]), sizeof(int), pan_array_size, file) != pan_array_size) { goto load_error; } /* playbacks pans and volumes */ - if (fread((void *)&(playbacks->strips[channel]->data[card][speed][preset]->pan_pos[0]), sizeof(int), 14, file) != 14) { + if (fread((void *)&(playbacks->strips[channel]->data[card][speed][preset]->pan_pos[0]), sizeof(int), pan_array_size, file) != pan_array_size) { goto load_error; } - if (fread((void *)&(playbacks->strips[channel]->data[card][speed][preset]->fader_pos[0]), sizeof(int), 14, file) != 14) { + if (fread((void *)&(playbacks->strips[channel]->data[card][speed][preset]->fader_pos[0]), sizeof(int), pan_array_size, file) != pan_array_size) { goto load_error; } /* inputs mute/solo/dest */
When reading a preset file, v1.0.23 only used 26 channels instead of 64. Reading 64 channels from a 26 channel file won't work, hence set it depending on the file format version.
Signed-off-by: Adrian Knoth adi@drcomp.erfurt.thur.de
diff --git a/hdspmixer/src/HDSPMixerWindow.cxx b/hdspmixer/src/HDSPMixerWindow.cxx index d6d28e3..fb41721 100644 --- a/hdspmixer/src/HDSPMixerWindow.cxx +++ b/hdspmixer/src/HDSPMixerWindow.cxx @@ -488,6 +488,7 @@ void HDSPMixerWindow::load() char buffer[sizeof(header)]; bool ondisk_v1 = false; int pan_array_size = 14; /* old (pre 1.0.24) HDSP_MAX_DEST */ + int channels_per_card = 26; /* old (pre 1.0.24) HDSP_MAX_CHANNELS */
if (fread(&buffer, sizeof(char), sizeof(buffer), file) != sizeof(buffer)) { goto load_error; @@ -496,6 +497,7 @@ void HDSPMixerWindow::load() /* new ondisk format found */ ondisk_v1 = true; pan_array_size = HDSP_MAX_DEST; + channels_per_card = HDSP_MAX_CHANNELS; } else { /* old format, rewind to the start and simply read all data */ rewind(file); @@ -504,7 +506,7 @@ void HDSPMixerWindow::load() for (int speed = 0; speed < 3; ++speed) { for (int card = 0; card < MAX_CARDS; ++card) { for (int preset = 0; preset < 8; ++preset) { - for (int channel = 0; channel < HDSP_MAX_CHANNELS; ++channel) { + for (int channel = 0; channel < channels_per_card; ++channel) { /* inputs pans and volumes */ if (fread((void *)&(inputs->strips[channel]->data[card][speed][preset]->pan_pos[0]), sizeof(int), pan_array_size, file) != pan_array_size) { goto load_error;
As an addition to the previous commit, let's also cover the 3rd case when a preset file was written with hdspmixer v1.0.24 or v1.0.24.1.
In this case, no magic header will be present, but the file size would differ from the pre 1.0.24 format.
Signed-off-by: Adrian Knoth adi@drcomp.erfurt.thur.de
diff --git a/hdspmixer/src/HDSPMixerWindow.cxx b/hdspmixer/src/HDSPMixerWindow.cxx index fb41721..74b5630 100644 --- a/hdspmixer/src/HDSPMixerWindow.cxx +++ b/hdspmixer/src/HDSPMixerWindow.cxx @@ -499,7 +499,24 @@ void HDSPMixerWindow::load() pan_array_size = HDSP_MAX_DEST; channels_per_card = HDSP_MAX_CHANNELS; } else { - /* old format, rewind to the start and simply read all data */ + /* There are two different kinds of old format: pre 1.0.24 and + * the one used for 1.0.24/1.0.24.1. We can distinguish between + * these two by checking the file size, becase HDSP_MAX_CHANNELS + * was bumped right before the 1.0.24 release. + */ + fseek (file, 0, SEEK_END); + long filesize = ftell (file); + + if (1163808 == filesize) { + /* file written by hdspmixer v1.0.24 or v1.0.24.1 with + * HDSP_MAX_CHANNELS set to 64, but pan_array_size still at + * 14, so setting channels_per_card should get the correct + * mapping. + */ + channels_per_card = 64; /* HDSP_MAX_CHANNELS */ + } + + /* rewind to the start and simply read all data */ rewind(file); }
At Fri, 8 Apr 2011 19:58:34 +0200, Adrian Knoth wrote:
Hi!
This small series of patches now detects three different file formats for hdspmixer's preset file:
- pre 1.0.24
- 1.0.24 and 1.0.24.1
- new format with magic header
This should catch almost all mix files available in the wild unless those files were written with an unreleased development version of hdspmixer in the last few weeks.
Applied now. (Sorry for the late reaction, as I've been sick.)
thanks,
Takashi
Cheers
Adrian Knoth (3): hdspmixer: Fix read/write from/to preset files on MADI-like cards hdspmixer: Handle channel count in old (v1.0.23) preset file format hdspmixer: Handle preset files used in 1.0.24 and 1.0.24.1
hdspmixer/src/HDSPMixerWindow.cxx | 60 ++++++++++++++++++++++++++++++------ 1 files changed, 50 insertions(+), 10 deletions(-)
-- 1.7.4.1
participants (2)
-
Adrian Knoth
-
Takashi Iwai