static void metadata_callback_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) { DecoderInstance *instance = (DecoderInstance*)client_data; (void)decoder; if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { instance->bits_per_sample = metadata->data.stream_info.bits_per_sample; instance->channels = metadata->data.stream_info.channels; instance->sample_rate = metadata->data.stream_info.sample_rate; if(instance->channels != 1 && instance->channels != 2) { instance->error = true; return; } if(!grabbag__replaygain_is_valid_sample_frequency(instance->sample_rate)) { instance->error = true; return; } } }
FLAC__bool do_shorthand_operation__add_replay_gain(char **filenames, unsigned num_files, FLAC__bool preserve_modtime) { FLAC__StreamMetadata streaminfo; float *title_gains = 0, *title_peaks = 0; float album_gain, album_peak; unsigned sample_rate = 0; unsigned bits_per_sample = 0; unsigned channels = 0; unsigned i; const char *error; FLAC__bool first = true; FLAC__ASSERT(num_files > 0); for(i = 0; i < num_files; i++) { FLAC__ASSERT(0 != filenames[i]); if(!FLAC__metadata_get_streaminfo(filenames[i], &streaminfo)) { fprintf(stderr, "%s: ERROR: can't open file or get STREAMINFO block\n", filenames[i]); return false; } if(first) { first = false; sample_rate = streaminfo.data.stream_info.sample_rate; bits_per_sample = streaminfo.data.stream_info.bits_per_sample; channels = streaminfo.data.stream_info.channels; } else { if(sample_rate != streaminfo.data.stream_info.sample_rate) { fprintf(stderr, "%s: ERROR: sample rate of %u Hz does not match previous files' %u Hz\n", filenames[i], streaminfo.data.stream_info.sample_rate, sample_rate); return false; } if(bits_per_sample != streaminfo.data.stream_info.bits_per_sample) { fprintf(stderr, "%s: ERROR: resolution of %u bps does not match previous files' %u bps\n", filenames[i], streaminfo.data.stream_info.bits_per_sample, bits_per_sample); return false; } if(channels != streaminfo.data.stream_info.channels) { fprintf(stderr, "%s: ERROR: # channels (%u) does not match previous files' (%u)\n", filenames[i], streaminfo.data.stream_info.channels, channels); return false; } } if(!grabbag__replaygain_is_valid_sample_frequency(sample_rate)) { fprintf(stderr, "%s: ERROR: sample rate of %u Hz is not supported\n", filenames[i], sample_rate); return false; } if(channels != 1 && channels != 2) { fprintf(stderr, "%s: ERROR: # of channels (%u) is not supported, must be 1 or 2\n", filenames[i], channels); return false; } } FLAC__ASSERT(bits_per_sample >= FLAC__MIN_BITS_PER_SAMPLE && bits_per_sample <= FLAC__MAX_BITS_PER_SAMPLE); if(!grabbag__replaygain_init(sample_rate)) { FLAC__ASSERT(0); /* double protection */ fprintf(stderr, "internal error\n"); return false; } if( 0 == (title_gains = (float*)malloc(sizeof(float) * num_files)) || 0 == (title_peaks = (float*)malloc(sizeof(float) * num_files)) ) die("out of memory allocating space for title gains/peaks"); for(i = 0; i < num_files; i++) { if(0 != (error = grabbag__replaygain_analyze_file(filenames[i], title_gains+i, title_peaks+i))) { fprintf(stderr, "%s: ERROR: during analysis (%s)\n", filenames[i], error); free(title_gains); free(title_peaks); return false; } } grabbag__replaygain_get_album(&album_gain, &album_peak); for(i = 0; i < num_files; i++) { if(0 != (error = grabbag__replaygain_store_to_file(filenames[i], album_gain, album_peak, title_gains[i], title_peaks[i], preserve_modtime))) { fprintf(stderr, "%s: ERROR: writing tags (%s)\n", filenames[i], error); free(title_gains); free(title_peaks); return false; } } free(title_gains); free(title_peaks); return true; }