1 /**********************************************************
2 * libmp3splt -- library based on mp3splt,
3 * for mp3/ogg splitting without decoding
4 *
5 * Copyright (c) 2002-2005 M. Trotta - <mtrotta@users.sourceforge.net>
6 * Copyright (c) 2005-2014 Alexandru Munteanu - m@ioalex.net
7 *
8 *********************************************************/
9
10 /**********************************************************
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
24 * USA.
25 *********************************************************/
26
27 #include <stdio.h>
28 #include <math.h>
29
30 #include "flac_silence.h"
31
32 static void splt_flac_scan_silence_and_process(splt_state *state, off_t start_offset,
33 float max_threshold, unsigned long length,
34 short process_silence(double time, float level, int silence_was_found, short must_flush,
35 splt_scan_silence_data *ssd, int *found, int *error),
36 splt_scan_silence_data *ssd, int *error);
37
splt_flac_scan_silence(splt_state * state,off_t start_offset,unsigned long length,float threshold,float min,int shots,short output,int * error,short silence_processor (double time,float level,int silence_was_found,short must_flush,splt_scan_silence_data * ssd,int * found,int * error))38 int splt_flac_scan_silence(splt_state *state, off_t start_offset, unsigned long length,
39 float threshold, float min, int shots, short output, int *error,
40 short silence_processor(double time, float level, int silence_was_found, short must_flush,
41 splt_scan_silence_data *ssd, int *found, int *error))
42 {
43 splt_scan_silence_data *ssd = splt_scan_silence_data_new(state, output, min, shots, SPLT_TRUE);
44 if (ssd == NULL)
45 {
46 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
47 return -1;
48 }
49
50 splt_flac_scan_silence_and_process(state, start_offset, threshold, length, silence_processor, ssd, error);
51
52 int found = ssd->found;
53
54 splt_free_scan_silence_data(&ssd);
55
56 if (*error < 0)
57 {
58 found = -1;
59 }
60
61 return found;
62 }
63
splt_flac_silence_data_new(splt_state * state,splt_flac_state * flacstate)64 static splt_flac_silence_data *splt_flac_silence_data_new(splt_state *state,
65 splt_flac_state *flacstate) {
66 splt_flac_silence_data *silence_data = malloc(sizeof(splt_flac_silence_data));
67 if (silence_data == NULL) { return NULL; }
68
69 silence_data->error = SPLT_OK;
70 silence_data->state = state;
71 silence_data->flacstate = flacstate;
72 silence_data->time = 0;
73 silence_data->silence_found = 1;
74 silence_data->threshold = 0;
75
76 return silence_data;
77 }
78
splt_flac_silence_data_free(splt_flac_silence_data * silence_data)79 static void splt_flac_silence_data_free(splt_flac_silence_data *silence_data)
80 {
81 if (!silence_data) { return; }
82 free(silence_data);
83 }
84
splt_flac_write_callback(const FLAC__StreamDecoder * decoder,const FLAC__Frame * frame,const FLAC__int32 * const buffer[],void * client_data)85 static FLAC__StreamDecoderWriteStatus splt_flac_write_callback(const FLAC__StreamDecoder *decoder,
86 const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
87 {
88 splt_flac_silence_data *silence_data = (splt_flac_silence_data *) client_data;
89 splt_flac_state *flacstate = silence_data->flacstate;
90
91 double number;
92 if (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER)
93 {
94 number = (double) frame->header.number.sample_number;
95 }
96 else
97 {
98 number = (double) frame->header.number.frame_number;
99 }
100
101 double time = (double) number / (double) frame->header.sample_rate;
102 silence_data->time = time;
103
104 silence_data->silence_found = 1;
105
106 size_t i, j;
107 for (i = 0;i < frame->header.channels; i++)
108 {
109 for (j = 0;j < frame->header.blocksize; j++)
110 {
111 float normalizer_coeff = 1.0 / ((1 << (frame->header.bits_per_sample - 1)));
112 float sample = fabs(buffer[i][j] * normalizer_coeff);
113 flacstate->temp_level = flacstate->temp_level * 0.999 + sample * 0.001;
114 if (sample > silence_data->threshold)
115 {
116 silence_data->silence_found = 0;
117 }
118 }
119 }
120
121 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
122 }
123
splt_flac_error_callback(const FLAC__StreamDecoder * decoder,FLAC__StreamDecoderErrorStatus status,void * client_data)124 static void splt_flac_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status,
125 void *client_data)
126 {
127 splt_flac_silence_data *silence_data = (splt_flac_silence_data *) client_data;
128
129 splt_e_set_error_data(silence_data->state, splt_t_get_filename_to_split(silence_data->state));
130 silence_data->error = SPLT_ERROR_INVALID;
131
132 splt_d_print_debug(silence_data->state, "Error while decoding flac file: %s\n",
133 FLAC__StreamDecoderErrorStatusString[status]);
134 }
135
splt_flac_scan_silence_and_process(splt_state * state,off_t start_offset,float max_threshold,unsigned long length,short process_silence (double time,float level,int silence_was_found,short must_flush,splt_scan_silence_data * ssd,int * found,int * error),splt_scan_silence_data * ssd,int * error)136 static void splt_flac_scan_silence_and_process(splt_state *state, off_t start_offset,
137 float max_threshold, unsigned long length,
138 short process_silence(double time, float level, int silence_was_found, short must_flush,
139 splt_scan_silence_data *ssd, int *found, int *error),
140 splt_scan_silence_data *ssd, int *error)
141 {
142 splt_c_put_progress_text(state, SPLT_PROGRESS_SCAN_SILENCE);
143
144 splt_flac_state *flacstate = state->codec;
145 splt_flac_silence_data *silence_data = splt_flac_silence_data_new(state, flacstate);
146 if (!silence_data)
147 {
148 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
149 return;
150 }
151
152 silence_data->threshold = splt_co_convert_from_db(max_threshold);
153
154 FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new();
155 if (decoder == NULL)
156 {
157 splt_flac_silence_data_free(silence_data);
158 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
159 return;
160 }
161
162 flacstate->temp_level = 0.0;
163
164 FLAC__StreamDecoderInitStatus status;
165 char *input_filename = splt_t_get_filename_to_split(state);
166 FILE *file = splt_io_fopen(input_filename, "rb");
167 if (file == NULL)
168 {
169 splt_e_set_strerror_msg_with_data(state, input_filename);
170 *error = SPLT_ERROR_CANNOT_OPEN_FILE;
171 splt_flac_silence_data_free(silence_data);
172 return;
173 }
174
175 if (start_offset > 0)
176 {
177 if (fseeko(file, start_offset, SEEK_SET) == -1)
178 {
179 splt_e_set_strerror_msg_with_data(state, input_filename);
180 *error = SPLT_ERROR_SEEKING_FILE;
181 splt_flac_silence_data_free(silence_data);
182 fclose(file);
183 return;
184 }
185 }
186
187 status = FLAC__stream_decoder_init_FILE(decoder, file,
188 splt_flac_write_callback, NULL, splt_flac_error_callback, silence_data);
189 if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK)
190 {
191 splt_d_print_debug(state, "Failed to initialize flac decoder with error %d", status);
192 splt_e_set_error_data(state, splt_t_get_filename_to_split(state));
193 *error = SPLT_ERROR_INVALID;
194 goto end;
195 }
196
197 int split_type = splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE);
198 short option_silence_mode =
199 (split_type == SPLT_OPTION_SILENCE_MODE || split_type == SPLT_OPTION_TRIM_SILENCE_MODE);
200
201 long total_time = splt_t_get_total_time(state);
202
203 int first_time = SPLT_TRUE;
204 long time0 = 0;
205 int found = 0;
206 while (FLAC__STREAM_DECODER_END_OF_STREAM != FLAC__stream_decoder_get_state(decoder))
207 {
208 if (!FLAC__stream_decoder_process_single(decoder))
209 {
210 break;
211 }
212
213 if (first_time)
214 {
215 time0 = silence_data->time;
216 }
217
218 first_time = SPLT_FALSE;
219
220 float level = splt_co_convert_to_db(flacstate->temp_level);
221 if (level < -96.0) { level = -96.0; }
222 if (level > 0) { level = 0; }
223
224 long current_time = (long) ((silence_data->time - time0) * 100);
225
226 short must_flush = length > 0 && current_time >= length;
227 int err = SPLT_OK;
228 short stop = process_silence(silence_data->time, level,
229 silence_data->silence_found, must_flush, ssd, &found, &err);
230 if (stop || stop == -1)
231 {
232 if (err < 0) { *error = err; goto end; }
233 break;
234 }
235
236 if (state->split.get_silence_level)
237 {
238 state->split.get_silence_level((long) (silence_data->time * 100.0), level, state->split.silence_level_client_data);
239 }
240 state->split.p_bar->silence_db_level = level;
241 state->split.p_bar->silence_found_tracks = found;
242
243 if (option_silence_mode)
244 {
245 if (splt_t_split_is_canceled(state)) { break; }
246 splt_c_update_progress(state, silence_data->time * 100.0, (double)total_time, 1, 0, SPLT_DEFAULT_PROGRESS_RATE2);
247 }
248 else
249 {
250 splt_c_update_progress(state, (double) current_time, (double)length, 4, 0.5, SPLT_DEFAULT_PROGRESS_RATE2);
251 }
252 }
253
254 if (silence_data->error < 0)
255 {
256 *error = silence_data->error;
257 }
258
259 end:
260 FLAC__stream_decoder_delete(decoder);
261 splt_flac_silence_data_free(silence_data);
262 }
263
264