mirror of
				https://github.com/alsa-project/alsa-tools.git
				synced 2025-10-29 05:40:25 -04:00 
			
		
		
		
	hdspmixer: enhance saving of presets
Changing the version in the file header would make a preset file not readable by older versions of the tool. If we just append new data always at the end of the save procedure we should have no problems reading them with different versions, as they all just read to a certain point and ignore the rest of the file. This patch implements the logic to save the presets first to a file called file_name.tmp and appends any extra data that would come after in a possibly present file_name file. Any data written by newer versions would remain in the preset file and from now on no old version should remove data written by newer versions. Also since we write to a temporary file and rename afterwards an extra feature is gained of not corrupting the preset should we crash. Signed-off-by: Jasmin Fazlic <superfassl@gmail.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
		
							parent
							
								
									82979c32e4
								
							
						
					
					
						commit
						c0e69055fa
					
				
					 1 changed files with 62 additions and 32 deletions
				
			
		|  | @ -353,18 +353,25 @@ void HDSPMixerWindow::save() | ||||||
|             sizeof(inputs->strips[0]->data[0][0][0]->fader_pos) / |             sizeof(inputs->strips[0]->data[0][0][0]->fader_pos) / | ||||||
|             sizeof(inputs->strips[0]->data[0][0][0]->fader_pos[0])); |             sizeof(inputs->strips[0]->data[0][0][0]->fader_pos[0])); | ||||||
| 
 | 
 | ||||||
|  | 	FILE *in,*out; | ||||||
| 
 | 
 | ||||||
|     FILE *file; | 	/* We want to append any existing extra data that might got written by a
 | ||||||
|  | 	 * newer version to this file, therefore write our data to file_name.tmp | ||||||
|  | 	 * and append the old data. Also this way we would not corrupt the file | ||||||
|  | 	 * should we crash. | ||||||
|  | 	 */ | ||||||
|  | 	std::string const tmp = file_name + std::string(".tmp"); | ||||||
|  | 	char const * const tmpc = tmp.c_str(); | ||||||
| 
 | 
 | ||||||
|     if ((file = fopen(file_name, "w")) == NULL) { |     if ((out = fopen(tmpc, "w")) == NULL) { | ||||||
| 	fl_alert("Error opening file %s for saving", file_name); | 	fl_alert("Error opening file %s for saving", tmpc); | ||||||
|     } |     } | ||||||
|     if (dirty) { |     if (dirty) { | ||||||
| 	inputs->buttons->presets->save_preset(current_preset+1); | 	inputs->buttons->presets->save_preset(current_preset+1); | ||||||
|     } |     } | ||||||
|     /* since hdspmixer 1.11, we also store the meter level settings. Indicate
 |     /* since hdspmixer 1.11, we also store the meter level settings. Indicate
 | ||||||
|      * the new on-disk structure via a small header */ |      * the new on-disk structure via a small header */ | ||||||
|     if (fwrite((void *)&header, sizeof(char), sizeof(header), file) != |     if (fwrite((void *)&header, sizeof(char), sizeof(header), out) != | ||||||
|             sizeof(header)) { |             sizeof(header)) { | ||||||
|         goto save_error; |         goto save_error; | ||||||
|     } |     } | ||||||
|  | @ -374,99 +381,122 @@ void HDSPMixerWindow::save() | ||||||
| 	    for (int preset = 0; preset < 8; ++preset) { | 	    for (int preset = 0; preset < 8; ++preset) { | ||||||
| 		for (int channel = 0; channel < HDSP_MAX_CHANNELS; ++channel) { | 		for (int channel = 0; channel < HDSP_MAX_CHANNELS; ++channel) { | ||||||
| 		    /* inputs pans and volumes */ | 		    /* inputs pans and volumes */ | ||||||
| 		    if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->pan_pos[0]), sizeof(int), pan_array_size, file) != pan_array_size) { | 		    if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->pan_pos[0]), sizeof(int), pan_array_size, out) != pan_array_size) { | ||||||
| 			goto save_error; | 			goto save_error; | ||||||
| 		    } | 		    } | ||||||
| 		    if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->fader_pos[0]), sizeof(int), pan_array_size, file) != pan_array_size) { | 		    if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->fader_pos[0]), sizeof(int), pan_array_size, out) != pan_array_size) { | ||||||
| 			goto save_error; | 			goto save_error; | ||||||
| 		    } | 		    } | ||||||
| 		    /* playbacks pans and volumes */ | 		    /* playbacks pans and volumes */ | ||||||
| 		    if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->pan_pos[0]), sizeof(int), pan_array_size, file) != pan_array_size) { | 		    if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->pan_pos[0]), sizeof(int), pan_array_size, out) != pan_array_size) { | ||||||
| 			goto save_error; | 			goto save_error; | ||||||
| 		    } | 		    } | ||||||
| 		    if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->fader_pos[0]), sizeof(int), pan_array_size, file) != pan_array_size) { | 		    if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->fader_pos[0]), sizeof(int), pan_array_size, out) != pan_array_size) { | ||||||
| 			goto save_error; | 			goto save_error; | ||||||
| 		    } | 		    } | ||||||
| 		    /* inputs mute/solo/dest */ | 		    /* inputs mute/solo/dest */ | ||||||
| 		    if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->mute), sizeof(int), 1, file) != 1) { | 		    if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->mute), sizeof(int), 1, out) != 1) { | ||||||
| 			goto save_error; | 			goto save_error; | ||||||
| 		    } | 		    } | ||||||
| 		    if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->solo), sizeof(int), 1, file) != 1) { | 		    if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->solo), sizeof(int), 1, out) != 1) { | ||||||
| 			goto save_error; | 			goto save_error; | ||||||
| 		    } | 		    } | ||||||
| 		    if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->dest), sizeof(int), 1, file) != 1) { | 		    if (fwrite((void *)&(inputs->strips[channel]->data[card][speed][preset]->dest), sizeof(int), 1, out) != 1) { | ||||||
| 			goto save_error; | 			goto save_error; | ||||||
| 		    } | 		    } | ||||||
| 		    /* playbacks mute/solo/dest */ | 		    /* playbacks mute/solo/dest */ | ||||||
| 		    if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->mute), sizeof(int), 1, file) != 1) { | 		    if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->mute), sizeof(int), 1, out) != 1) { | ||||||
| 			goto save_error; | 			goto save_error; | ||||||
| 		    } | 		    } | ||||||
| 		    if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->solo), sizeof(int), 1, file) != 1) { | 		    if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->solo), sizeof(int), 1, out) != 1) { | ||||||
| 			goto save_error; | 			goto save_error; | ||||||
| 		    } | 		    } | ||||||
| 		    if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->dest), sizeof(int), 1, file) != 1) { | 		    if (fwrite((void *)&(playbacks->strips[channel]->data[card][speed][preset]->dest), sizeof(int), 1, out) != 1) { | ||||||
| 			goto save_error; | 			goto save_error; | ||||||
| 		    } | 		    } | ||||||
| 		    /* outputs volumes */ | 		    /* outputs volumes */ | ||||||
| 		    if (fwrite((void *)&(outputs->strips[channel]->data[card][speed][preset]->fader_pos), sizeof(int), 1, file) != 1) { | 		    if (fwrite((void *)&(outputs->strips[channel]->data[card][speed][preset]->fader_pos), sizeof(int), 1, out) != 1) { | ||||||
| 			goto save_error; | 			goto save_error; | ||||||
| 		    } | 		    } | ||||||
| 		     | 		     | ||||||
|  		} |  		} | ||||||
| 		/* Lineouts */		     | 		/* Lineouts */		     | ||||||
| 		if (fwrite((void *)&(outputs->strips[HDSP_MAX_CHANNELS]->data[card][speed][preset]->fader_pos), sizeof(int), 1, file) != 1) { | 		if (fwrite((void *)&(outputs->strips[HDSP_MAX_CHANNELS]->data[card][speed][preset]->fader_pos), sizeof(int), 1, out) != 1) { | ||||||
| 		    goto save_error; | 		    goto save_error; | ||||||
| 		} | 		} | ||||||
| 		if (fwrite((void *)&(outputs->strips[HDSP_MAX_CHANNELS+1]->data[card][speed][preset]->fader_pos), sizeof(int), 1, file) != 1) { | 		if (fwrite((void *)&(outputs->strips[HDSP_MAX_CHANNELS+1]->data[card][speed][preset]->fader_pos), sizeof(int), 1, out) != 1) { | ||||||
| 		    goto save_error; | 		    goto save_error; | ||||||
| 		} | 		} | ||||||
| 		/* Global settings */ | 		/* Global settings */ | ||||||
| 		if (fwrite((void *)&(data[card][speed][preset]->input), sizeof(int), 1, file) != 1) { | 		if (fwrite((void *)&(data[card][speed][preset]->input), sizeof(int), 1, out) != 1) { | ||||||
| 		    goto save_error; | 		    goto save_error; | ||||||
| 		} | 		} | ||||||
| 		if (fwrite((void *)&(data[card][speed][preset]->output), sizeof(int), 1, file) != 1) { | 		if (fwrite((void *)&(data[card][speed][preset]->output), sizeof(int), 1, out) != 1) { | ||||||
| 		    goto save_error; | 		    goto save_error; | ||||||
| 		} | 		} | ||||||
| 		if (fwrite((void *)&(data[card][speed][preset]->playback), sizeof(int), 1, file) != 1) { | 		if (fwrite((void *)&(data[card][speed][preset]->playback), sizeof(int), 1, out) != 1) { | ||||||
| 		    goto save_error; | 		    goto save_error; | ||||||
| 		} | 		} | ||||||
| 		if (fwrite((void *)&(data[card][speed][preset]->submix), sizeof(int), 1, file) != 1) { | 		if (fwrite((void *)&(data[card][speed][preset]->submix), sizeof(int), 1, out) != 1) { | ||||||
| 		    goto save_error; | 		    goto save_error; | ||||||
| 		} | 		} | ||||||
| 		if (fwrite((void *)&(data[card][speed][preset]->submix_value), sizeof(int), 1, file) != 1) { | 		if (fwrite((void *)&(data[card][speed][preset]->submix_value), sizeof(int), 1, out) != 1) { | ||||||
| 		    goto save_error; | 		    goto save_error; | ||||||
| 		} | 		} | ||||||
| 		if (fwrite((void *)&(data[card][speed][preset]->solo), sizeof(int), 1, file) != 1) { | 		if (fwrite((void *)&(data[card][speed][preset]->solo), sizeof(int), 1, out) != 1) { | ||||||
| 		    goto save_error; | 		    goto save_error; | ||||||
| 		} | 		} | ||||||
| 		if (fwrite((void *)&(data[card][speed][preset]->mute), sizeof(int), 1, file) != 1) { | 		if (fwrite((void *)&(data[card][speed][preset]->mute), sizeof(int), 1, out) != 1) { | ||||||
| 		    goto save_error; | 		    goto save_error; | ||||||
| 		}		 | 		}		 | ||||||
| 		if (fwrite((void *)&(data[card][speed][preset]->last_destination), sizeof(int), 1, file) != 1) { | 		if (fwrite((void *)&(data[card][speed][preset]->last_destination), sizeof(int), 1, out) != 1) { | ||||||
| 		    goto save_error; | 		    goto save_error; | ||||||
| 		} | 		} | ||||||
| 		if (fwrite((void *)&(data[card][speed][preset]->rmsplus3), sizeof(int), 1, file) != 1) { | 		if (fwrite((void *)&(data[card][speed][preset]->rmsplus3), sizeof(int), 1, out) != 1) { | ||||||
| 		    goto save_error; | 		    goto save_error; | ||||||
| 		} | 		} | ||||||
| 		if (fwrite((void *)&(data[card][speed][preset]->numbers), sizeof(int), 1, file) != 1) { | 		if (fwrite((void *)&(data[card][speed][preset]->numbers), sizeof(int), 1, out) != 1) { | ||||||
| 		    goto save_error; | 		    goto save_error; | ||||||
| 		} | 		} | ||||||
| 		if (fwrite((void *)&(data[card][speed][preset]->over), sizeof(int), 1, file) != 1) { | 		if (fwrite((void *)&(data[card][speed][preset]->over), sizeof(int), 1, out) != 1) { | ||||||
| 		    goto save_error; | 		    goto save_error; | ||||||
| 		} | 		} | ||||||
| 		if (fwrite((void *)&(data[card][speed][preset]->level), sizeof(int), 1, file) != 1) { | 		if (fwrite((void *)&(data[card][speed][preset]->level), sizeof(int), 1, out) != 1) { | ||||||
| 		    goto save_error; | 		    goto save_error; | ||||||
| 		} | 		} | ||||||
| 		if (fwrite((void *)&(data[card][speed][preset]->rate), sizeof(int), 1, file) != 1) { | 		if (fwrite((void *)&(data[card][speed][preset]->rate), sizeof(int), 1, out) != 1) { | ||||||
| 		    goto save_error; | 		    goto save_error; | ||||||
| 		} | 		} | ||||||
| 	    } | 	    } | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
|     fclose(file); | 
 | ||||||
|  | 	/* If the file we want to write already exists it could be possible that it
 | ||||||
|  | 	* was saved with a newer version. If that is the case we just append its | ||||||
|  | 	* content to the new output file and that way ensure that we don't lose any | ||||||
|  | 	* data the new version wrote. | ||||||
|  | 	*/ | ||||||
|  | 	if ((in = fopen(file_name, "r")) != NULL) { | ||||||
|  | 		if (!fseek(in, ftell(out), SEEK_SET)) { | ||||||
|  | 			char buff[512]; | ||||||
|  | 			size_t read; | ||||||
|  | 			while ((read = fread(&buff, sizeof(char), sizeof(buff), in)) != 0) | ||||||
|  | 				fwrite(buff, sizeof(char), read, out); | ||||||
|  | 			if (ferror(in) || ferror(out)) | ||||||
|  | 				fl_alert("Error appending %s to %s", file_name, tmpc); | ||||||
|  | 		} | ||||||
|  | 		fclose(in); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fclose(out); | ||||||
|  | 
 | ||||||
|  | 	if (rename(tmpc, file_name)) | ||||||
|  | 		fl_alert("Error renaming %s to %s", tmpc, file_name); | ||||||
|  | 	::remove(tmpc); | ||||||
|  | 
 | ||||||
|     return; |     return; | ||||||
| save_error: | save_error: | ||||||
|     fclose(file); |     fclose(out); | ||||||
|     fl_alert("Error saving presets to file %s", file_name); |     fl_alert("Error saving presets to file %s", file_name); | ||||||
|     return; |     return; | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jasmin Fazlic
						Jasmin Fazlic