Skip to content

Commit

Permalink
Add option to metaflac to write to different file
Browse files Browse the repository at this point in the history
  • Loading branch information
ktmf01 committed Oct 25, 2024
1 parent 1661902 commit 7446a12
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 13 deletions.
7 changes: 6 additions & 1 deletion man/metaflac.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,13 @@ modification time is set to the current time):

# OPTIONS

**-o** *filename***, \--output-name=***filename*
: Output to a new file instead of changing or rewriting the input
file.

**\--preserve-modtime**
: Preserve the original modification time in spite of edits.
: Preserve the original modification time in spite of edits. This does
nothing when -o or --output-name are specified.

**\--with-filename**
: Prefix each output line with the FLAC file name (the default if more
Expand Down
10 changes: 8 additions & 2 deletions src/metaflac/operations.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,10 @@ FLAC__bool do_major_operation_on_file(const char *filename, const CommandLineOpt
if(ok && needs_write) {
if(options->use_padding)
FLAC__metadata_chain_sort_padding(chain);
ok = FLAC__metadata_chain_write(chain, options->use_padding, options->preserve_modtime);
if(options->output_name == 0)
ok = FLAC__metadata_chain_write(chain, options->use_padding, options->preserve_modtime);
else
ok = FLAC__metadata_chain_write_new_file(chain, options->output_name, options->use_padding);
if(!ok) {
FLAC__Metadata_ChainStatus status = FLAC__metadata_chain_status(chain);
print_error_with_chain_status(chain, "%s: ERROR: writing FLAC file", filename);
Expand Down Expand Up @@ -469,7 +472,10 @@ FLAC__bool do_shorthand_operations_on_file(const char *filename, const CommandLi
if(ok && needs_write) {
if(use_padding)
FLAC__metadata_chain_sort_padding(chain);
ok = FLAC__metadata_chain_write(chain, use_padding, options->preserve_modtime);
if(options->output_name == 0)
ok = FLAC__metadata_chain_write(chain, use_padding, options->preserve_modtime);
else
ok = FLAC__metadata_chain_write_new_file(chain, options->output_name, use_padding);
if(!ok) {
FLAC__Metadata_ChainStatus status = FLAC__metadata_chain_status(chain);
print_error_with_chain_status(chain, "%s: ERROR: writing FLAC file", filename);
Expand Down
20 changes: 14 additions & 6 deletions src/metaflac/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
*/
struct share__option long_options_[] = {
/* global options */
{ "output-name", 1, 0, 'o' }, /* NOTE: if this option moves in this list, change the index in parse_options */
{ "preserve-modtime", 0, 0, 0 },
{ "with-filename", 0, 0, 0 },
{ "no-filename", 0, 0, 0 },
Expand Down Expand Up @@ -158,6 +159,7 @@ void init_options(CommandLineOptions *options)

options->num_files = 0;
options->filenames = 0;
options->output_name = 0;
}

FLAC__bool parse_options(int argc, char *argv[], CommandLineOptions *options)
Expand All @@ -166,11 +168,14 @@ FLAC__bool parse_options(int argc, char *argv[], CommandLineOptions *options)
int option_index = 1;
FLAC__bool had_error = false;

while ((ret = share__getopt_long(argc, argv, "", long_options_, &option_index)) != -1) {
while ((ret = share__getopt_long(argc, argv, "o:", long_options_, &option_index)) != -1) {
switch (ret) {
case 0:
had_error |= !parse_option(option_index, share__optarg, options);
break;
case 'o':
had_error |= !parse_option(0, share__optarg, options);
break;
case '?':
case ':':
had_error = true;
Expand Down Expand Up @@ -213,6 +218,10 @@ FLAC__bool parse_options(int argc, char *argv[], CommandLineOptions *options)

/* check for only one FLAC file used with certain options */
if(!had_error && options->num_files > 1) {
if(0 != options->output_name) {
flac_fprintf(stderr, "ERROR: you may only specify one FLAC input file when specifying an output filename\n");
had_error = true;
}
if(0 != find_shorthand_operation(options, OP__IMPORT_CUESHEET_FROM)) {
flac_fprintf(stderr, "ERROR: you may only specify one FLAC file when using '--import-cuesheet-from'\n");
had_error = true;
Expand Down Expand Up @@ -327,10 +336,6 @@ void free_options(CommandLineOptions *options)
if(0 != arg->value.block_type.entries)
free(arg->value.block_type.entries);
break;
case ARG__FROM_FILE:
if(0 != arg->value.from_file.file_name)
free(arg->value.from_file.file_name);
break;
default:
break;
}
Expand Down Expand Up @@ -380,6 +385,9 @@ FLAC__bool parse_option(int option_index, const char *option_argument, CommandLi
else if(0 == strcmp(opt, "no-cued-seekpoints")) {
options->cued_seekpoints = false;
}
else if(0 == strcmp(opt, "output-name")) {
options->output_name = option_argument;
}
else if(0 == strcmp(opt, "show-md5sum")) {
(void) append_shorthand_operation(options, OP__SHOW_MD5SUM);
}
Expand Down Expand Up @@ -731,7 +739,7 @@ FLAC__bool parse_option(int option_index, const char *option_argument, CommandLi
else if(0 == strcmp(opt, "from-file")) {
arg = append_argument(options, ARG__FROM_FILE);
FLAC__ASSERT(0 != option_argument);
arg->value.from_file.file_name = local_strdup(option_argument);
arg->value.from_file.file_name = option_argument;
}
else {
FLAC__ASSERT(0);
Expand Down
3 changes: 2 additions & 1 deletion src/metaflac/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ typedef struct {
} Argument_DataFormat;

typedef struct {
char *file_name;
const char *file_name;
} Argument_FromFile;

typedef struct {
Expand Down Expand Up @@ -212,6 +212,7 @@ typedef struct {
} args;
unsigned num_files;
char **filenames;
const char *output_name;
} CommandLineOptions;

void init_options(CommandLineOptions *options);
Expand Down
3 changes: 3 additions & 0 deletions src/metaflac/usage.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ static void usage_summary(FILE *out)
flac_fprintf(out, "You may perform one major operation, or many shorthand operations at a time.\n");
flac_fprintf(out, "\n");
flac_fprintf(out, "Options:\n");
flac_fprintf(out, "-o, --output-name=FILENAME Write changes to a new file, instead of doing all\n");
flac_fprintf(out, " operations on the input files\n");
flac_fprintf(out, "--preserve-modtime Preserve the original modification time in spite of edits\n");
flac_fprintf(out, " This option does nothing when combined with --output-name\n");
flac_fprintf(out, "--with-filename Prefix each output line with the FLAC file name\n");
flac_fprintf(out, " (the default if more than one FLAC file is specified).\n");
flac_fprintf(out, " This option has no effect for options exporting to a\n");
Expand Down
3 changes: 2 additions & 1 deletion test/metaflac-test-files/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ EXTRA_DIST = \
case64-expect.meta \
case65-expect.meta \
case66-expect.meta \
case67-expect.meta
case67-expect.meta \
case68-expect.meta

clean-local:
-rm -f out.*
96 changes: 96 additions & 0 deletions test/metaflac-test-files/case68-expect.meta
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
METADATA block #0
type: 0 (STREAMINFO)
is last: false
length: 34
minimum blocksize: 1152 samples
maximum blocksize: 1152 samples
minimum framesize: 11 bytes
maximum framesize: 11 bytes
sample_rate: 44100 Hz
channels: 1
bits-per-sample: 8
total samples: 1
MD5 signature: 8d39dd7eef115ea6975446ef4082951f
METADATA block #1
type: 126 (UNKNOWN)
is last: false
length: 4
data contents:
00000000: AA 55 A5 5A 00 00 00 00 00 00 00 00 00 00 00 00 .U.Z
METADATA block #2
type: 5 (CUESHEET)
is last: false
length: 480
media catalog number:
lead-in: 88200
is CD: true
number of tracks: 2
track[0]
offset: 0
number: 1
ISRC:
type: AUDIO
pre-emphasis: false
number of index points: 1
index[0]
offset: 0
number: 1
track[1]
offset: 1
number: 170 (LEAD-OUT)
METADATA block #3
type: 2 (APPLICATION)
is last: false
length: 12
application ID: 61626364
data contents:
calfflacMETADATA block #4
type: 3 (SEEKTABLE)
is last: false
length: 18
seek points: 1
point 0: sample_number=0, stream_offset=0, frame_samples=1
METADATA block #5
type: 4 (VORBIS_COMMENT)
is last: false
length: 82
vendor string: reference libFLAC 1.0.5_beta2 20030114
comments: 1
comment[0]: COMMENT=πŸ€”πŸ€”πŸ€”πŸ€”πŸ€”πŸ€”
METADATA block #6
type: 126 (UNKNOWN)
is last: false
length: 4
data contents:
00000000: AA 55 A5 5A 00 00 00 00 00 00 00 00 00 00 00 00 .U.Z
METADATA block #7
type: 5 (CUESHEET)
is last: false
length: 480
media catalog number:
lead-in: 88200
is CD: true
number of tracks: 2
track[0]
offset: 0
number: 1
ISRC:
type: AUDIO
pre-emphasis: false
number of index points: 1
index[0]
offset: 0
number: 1
track[1]
offset: 1
number: 170 (LEAD-OUT)
METADATA block #8
type: 2 (APPLICATION)
is last: false
length: 12
application ID: 61626364
data contents:
calfflacMETADATA block #9
type: 1 (PADDING)
is last: true
length: 28
70 changes: 68 additions & 2 deletions test/test_metaflac.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ fi

testdir="metaflac-test-files"
flacfile="metaflac1.flac"
flacfile_secondary="metaflac2.flac"

flac${EXE} --help 1>/dev/null 2>/dev/null || die "ERROR can't find flac executable"
metaflac${EXE} --help 1>/dev/null 2>/dev/null || die "ERROR can't find metaflac executable"
Expand Down Expand Up @@ -166,10 +167,19 @@ check_flac
metaflac_test case02 "--add-padding" "--list"

# some flavors of /bin/sh (e.g. Darwin's) won't even handle quoted spaces, so we underscore:
run_metaflac -o $flacfile_secondary --set-tag="ARTIST=The_artist_formerly_known_as_the_artist..." $flacfile
check_flac
metaflac_test case02 "whether -o does not change input file" "--list"

run_metaflac --set-tag="ARTIST=The_artist_formerly_known_as_the_artist..." $flacfile
check_flac
metaflac_test case03 "--set-tag=ARTIST" "--list"

rm $flacfile
mv $flacfile_secondary $flacfile
check_flac
metaflac_test case03 "-o --set-tag=ARTIST" "--list"

run_metaflac --set-tag="ARTIST=Chuck_Woolery" $flacfile
check_flac
metaflac_test case04 "--set-tag=ARTIST" "--list"
Expand Down Expand Up @@ -215,10 +225,19 @@ run_metaflac --add-padding=0 $flacfile
check_flac
metaflac_test case18 "--add-padding=0" "--list"

run_metaflac -o $flacfile_secondary --sort-padding $flacfile
check_flac
metaflac_test case18 "whether -o does not change input file" "--list"

run_metaflac --sort-padding $flacfile
check_flac
metaflac_test case19 "--sort-padding" "--list"

rm $flacfile
mv $flacfile_secondary $flacfile
check_flac
metaflac_test case19 "-o --sort-padding" "--list"

run_metaflac --add-padding=0 $flacfile
check_flac
metaflac_test case20 "--add-padding=0" "--list"
Expand All @@ -227,22 +246,58 @@ run_metaflac --remove-all-tags $flacfile
check_flac
metaflac_test case21 "--remove-all-tags" "--list"

run_metaflac -o $flacfile_secondary --remove --block-number=1,99 --dont-use-padding $flacfile
check_flac
metaflac_test case21 "whether -o does not change input file" "--list"

run_metaflac --remove --block-number=1,99 --dont-use-padding $flacfile
check_flac
metaflac_test case22 "--remove --block-number=1,99 --dont-use-padding" "--list"

rm $flacfile
mv $flacfile_secondary $flacfile
check_flac
metaflac_test case22 "-o --remove --block-number=1,99 --dont-use-padding" "--list"

run_metaflac -o $flacfile_secondary --remove --block-number=99 --dont-use-padding $flacfile
check_flac
metaflac_test case22 "whether -o does not change input file" "--list"

run_metaflac --remove --block-number=99 --dont-use-padding $flacfile
check_flac
metaflac_test case23 "--remove --block-number=99 --dont-use-padding" "--list"

rm $flacfile
mv $flacfile_secondary $flacfile
check_flac
metaflac_test case23 "-o --remove --block-number=99 --dont-use-padding" "--list"

run_metaflac -o $flacfile_secondary --remove --block-type=PADDING $flacfile
check_flac
metaflac_test case23 "whether -o does not change input file" "--list"

run_metaflac --remove --block-type=PADDING $flacfile
check_flac
metaflac_test case24 "--remove --block-type=PADDING" "--list"

rm $flacfile
mv $flacfile_secondary $flacfile
check_flac
metaflac_test case24 "-o --remove --block-type=PADDING" "--list"

run_metaflac -o $flacfile_secondary --remove --block-type=PADDING --dont-use-padding $flacfile
check_flac
metaflac_test case24 "whether -o does not change input file" "--list"

run_metaflac --remove --block-type=PADDING --dont-use-padding $flacfile
check_flac
metaflac_test case25 "--remove --block-type=PADDING --dont-use-padding" "--list"

rm $flacfile
mv $flacfile_secondary $flacfile
check_flac
metaflac_test case25 "-o --remove --block-type=PADDING --dont-use-padding" "--list"

run_metaflac --add-padding=0 $flacfile $flacfile
check_flac
metaflac_test case26 "--add-padding=0 * 2" "--list"
Expand Down Expand Up @@ -462,17 +517,28 @@ fi
if run_metaflac_to_metaflac_silent "--list --data-format=binary --except-block-type=STREAMINFO,SEEKTABLE,VORBIS_COMMENT $flacfile2" "--append $flacfile" ; then
:
else
die "ERROR, couldn't add vorbis comment metadata block"
die "ERROR, couldn't append metadata block"
fi

metaflac_test_nofilter case66 "--append" "--list"

if run_metaflac_to_metaflac_silent "--list --data-format=binary --except-block-type=STREAMINFO,SEEKTABLE,VORBIS_COMMENT $flacfile2" "--append --block-number=0 $flacfile" ; then
:
else
die "ERROR, couldn't add vorbis comment metadata block"
die "ERROR, couldn't insert metadata block"
fi

metaflac_test_nofilter case67 "--append --block-number=0" "--list"

run_metaflac -o $flacfile_secondary --set-tag=COMMENT=πŸ€”πŸ€”πŸ€”πŸ€”πŸ€”πŸ€” $flacfile
check_flac
metaflac_test_nofilter case67 "--set-tag with UTF-8 in different output file, check original file" "--list"
run_metaflac --set-tag=COMMENT=πŸ€”πŸ€”πŸ€”πŸ€”πŸ€”πŸ€” $flacfile
check_flac
metaflac_test_nofilter case68 "--set-tag with UTF-8 in same file" "--list"
rm $flacfile
mv $flacfile_secondary $flacfile
metaflac_test_nofilter case68 "--set-tag with UTF-8 in different output file, check new file" "--list"


rm -f metaflac-test-files/out.meta metaflac-test-files/out1.meta

0 comments on commit 7446a12

Please sign in to comment.