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 "silence_processors.h"
28
29 static void write_to_full_log(splt_state *state, double time, float level, int shots, int found,
30 double begin_position, double end_position);
31
splt_scan_silence_data_new(splt_state * state,short first,float min,int shots,short set_new_length)32 splt_scan_silence_data *splt_scan_silence_data_new(splt_state *state, short first,
33 float min, int shots, short set_new_length)
34 {
35 splt_scan_silence_data *ssd = malloc(sizeof(splt_scan_silence_data));
36 if (!ssd)
37 {
38 return NULL;
39 }
40
41 ssd->state = state;
42 ssd->first = first;
43 ssd->min = min;
44 ssd->number_of_shots = shots;
45 ssd->set_new_length = set_new_length;
46
47 ssd->flush = SPLT_FALSE;
48 ssd->silence_begin = 0;
49 ssd->silence_end = 0;
50 ssd->len = 0;
51 ssd->found = 0;
52 ssd->shot = shots;
53 ssd->silence_begin_was_found = SPLT_FALSE;
54 ssd->continue_after_silence = SPLT_FALSE;
55 ssd->previous_time = 0;
56
57 return ssd;
58 }
59
splt_free_scan_silence_data(splt_scan_silence_data ** ssd)60 void splt_free_scan_silence_data(splt_scan_silence_data **ssd)
61 {
62 if (!ssd || !*ssd)
63 {
64 return;
65 }
66
67 free(*ssd);
68 *ssd = NULL;
69 }
70
splt_scan_silence_processor(double time,float level,int silence_was_found,short must_flush,splt_scan_silence_data * ssd,int * found_silence_points,int * error)71 short splt_scan_silence_processor(double time, float level, int silence_was_found,
72 short must_flush, splt_scan_silence_data *ssd, int *found_silence_points, int *error)
73 {
74 if (time < 0) { return SPLT_TRUE; }
75
76 short stop = SPLT_FALSE;
77
78 if (must_flush)
79 {
80 ssd->flush = SPLT_TRUE;
81 stop = SPLT_TRUE;
82 }
83
84 if (!ssd->flush && silence_was_found)
85 {
86 if (ssd->len == 0)
87 {
88 ssd->silence_begin = time;
89 }
90
91 if (ssd->first == SPLT_FALSE)
92 {
93 ssd->len++;
94 }
95
96 if (ssd->shot < ssd->number_of_shots)
97 {
98 ssd->shot += 2;
99 }
100
101 ssd->silence_end = time;
102
103 *found_silence_points = ssd->found;
104
105 write_to_full_log(ssd->state, time, level, ssd->shot, ssd->found, -1, -1);
106 return stop;
107 }
108
109 double begin_position = -1;
110 double end_position = -1;
111
112 if (ssd->len > SPLT_DEFAULTSILLEN)
113 {
114 if (ssd->flush || (ssd->shot <= 0))
115 {
116 begin_position = ssd->silence_begin;
117 end_position = ssd->silence_end;
118
119 if (ssd->set_new_length)
120 {
121 ssd->len = (int) (ssd->silence_end * 100.0 - ssd->silence_begin * 100.0);
122 }
123
124 if ((end_position - begin_position - ssd->min) >= 0.f)
125 {
126 if (splt_siu_ssplit_new(&ssd->state->silence_list,
127 begin_position, end_position, ssd->len, error) == -1)
128 {
129 ssd->found = -1;
130 *found_silence_points = ssd->found;
131
132 write_to_full_log(ssd->state, time, level, ssd->shot, ssd->found, begin_position, end_position);
133 return SPLT_TRUE;
134 }
135
136 ssd->found++;
137 }
138
139 ssd->len = 0;
140 ssd->shot = ssd->number_of_shots;
141 }
142 }
143 else
144 {
145 ssd->len = 0;
146 }
147
148 if (ssd->flush)
149 {
150 write_to_full_log(ssd->state, time, level, ssd->shot, ssd->found, begin_position, end_position);
151 return -1;
152 }
153
154 if (ssd->first && (ssd->shot <= 0))
155 {
156 ssd->first = SPLT_FALSE;
157 }
158
159 if (ssd->shot > 0)
160 {
161 ssd->shot--;
162 }
163
164 if (ssd->found >= SPLT_MAXSILENCE)
165 {
166 stop = SPLT_TRUE;
167 }
168
169 *found_silence_points = ssd->found;
170
171 write_to_full_log(ssd->state, time, level, ssd->shot, ssd->found, begin_position, end_position);
172 return stop;
173 }
174
write_to_full_log(splt_state * state,double time,float level,int shots,int found,double begin_position,double end_position)175 static void write_to_full_log(splt_state *state, double time, float level, int shots, int found,
176 double begin_position, double end_position)
177 {
178 FILE *full_log_file_descriptor = splt_t_get_silence_full_log_file_descriptor(state);
179 if (!full_log_file_descriptor)
180 {
181 return;
182 }
183
184 if (begin_position > 0 && end_position > 0)
185 {
186 fprintf(full_log_file_descriptor, "0\t%lf\t%f\t%d\t%d\t%lf\t%lf\n", time, level, shots, found,
187 begin_position, end_position);
188 return;
189 }
190
191 fprintf(full_log_file_descriptor, "0\t%lf\t%f\t%d\t%d\t\t\n", time, level, shots, found);
192 }
193
splt_detect_where_begin_silence_ends(double time,float level,int silence_was_found,short must_flush,splt_scan_silence_data * ssd,int * found_silence_points,int * error)194 static short splt_detect_where_begin_silence_ends(double time, float level, int silence_was_found,
195 short must_flush, splt_scan_silence_data *ssd, int *found_silence_points, int *error)
196 {
197 if (silence_was_found)
198 {
199 if (ssd->shot < ssd->number_of_shots)
200 {
201 ssd->shot += 2;
202 }
203
204 ssd->silence_end = time;
205 }
206
207 if (ssd->shot <= 0)
208 {
209 double silence_end = ssd->silence_end;
210
211 float min_length = splt_o_get_float_option(ssd->state, SPLT_OPT_PARAM_MIN_LENGTH);
212 if (min_length > 0)
213 {
214 if (silence_end > min_length)
215 {
216 silence_end -= min_length;
217 }
218 else
219 {
220 silence_end = 0;
221 }
222
223 long mins, secs, hundr;
224 splt_co_get_mins_secs_hundr(splt_co_time_to_long(silence_end), &mins, &secs, &hundr);
225 splt_c_put_info_message_to_client(ssd->state,
226 _(" info: trim begin split at %ldm_%.2lds_%.2ldh\n"), mins, secs, hundr);
227 }
228
229 if (splt_siu_ssplit_new(&ssd->state->silence_list, silence_end, silence_end, 0, error) == -1)
230 {
231 return SPLT_TRUE;
232 }
233
234 ssd->found++;
235 ssd->silence_begin_was_found = SPLT_TRUE;
236 ssd->shot = ssd->number_of_shots;
237 }
238
239 if (ssd->shot > 0)
240 {
241 ssd->shot--;
242 }
243
244 return SPLT_FALSE;
245 }
246
splt_detect_where_end_silence_begins(double time,float level,int silence_was_found,short must_flush,splt_scan_silence_data * ssd,int * found_silence_points,int * error)247 static short splt_detect_where_end_silence_begins(double time, float level, int silence_was_found,
248 short must_flush, splt_scan_silence_data *ssd, int *found_silence_points, int *error)
249 {
250 if (time < 0)
251 {
252 double silence_begin = ssd->silence_begin;
253
254 float min_length = splt_o_get_float_option(ssd->state, SPLT_OPT_PARAM_MIN_LENGTH);
255 if (min_length > 0)
256 {
257 if (ssd->previous_time - silence_begin > min_length)
258 {
259 silence_begin += min_length;
260 }
261 else
262 {
263 silence_begin = ssd->previous_time;
264 }
265
266 long mins, secs, hundr;
267 splt_co_get_mins_secs_hundr(splt_co_time_to_long(silence_begin), &mins, &secs, &hundr);
268 splt_c_put_info_message_to_client(ssd->state,
269 _(" info: trim end split at %ldm_%.2lds_%.2ldh\n"), mins, secs, hundr);
270 }
271
272 if (splt_siu_ssplit_new(&ssd->state->silence_list, silence_begin, silence_begin, 0, error) == -1)
273 {
274 return SPLT_TRUE;
275 }
276
277 ssd->found++;
278
279 return SPLT_TRUE;
280 }
281
282 ssd->previous_time = time;
283
284 if (silence_was_found)
285 {
286 if (ssd->len == 0)
287 {
288 ssd->silence_begin = time;
289 ssd->continue_after_silence = SPLT_FALSE;
290 }
291
292 if (ssd->first == SPLT_FALSE)
293 {
294 ssd->len++;
295 }
296
297 if (ssd->shot < ssd->number_of_shots)
298 {
299 ssd->shot += 2;
300 }
301
302 return SPLT_FALSE;
303 }
304 else if (ssd->continue_after_silence)
305 {
306 ssd->silence_begin = time;
307 }
308
309 if (ssd->len > SPLT_DEFAULTSILLEN)
310 {
311 if (ssd->shot <= 0)
312 {
313 ssd->len = 0;
314 ssd->shot = ssd->number_of_shots;
315 ssd->continue_after_silence = SPLT_TRUE;
316 }
317 }
318 else
319 {
320 ssd->len = 0;
321 }
322
323 if (ssd->first && (ssd->shot <= 0))
324 {
325 ssd->first = SPLT_FALSE;
326 }
327
328 if (ssd->shot > 0)
329 {
330 ssd->shot--;
331 }
332
333 return SPLT_FALSE;
334 }
335
splt_trim_silence_processor(double time,float level,int silence_was_found,short must_flush,splt_scan_silence_data * ssd,int * found_silence_points,int * error)336 short splt_trim_silence_processor(double time, float level, int silence_was_found,
337 short must_flush, splt_scan_silence_data *ssd, int *found_silence_points, int *error)
338 {
339 if (!ssd->silence_begin_was_found)
340 {
341 splt_detect_where_begin_silence_ends(time, level, silence_was_found, must_flush, ssd, found_silence_points, error);
342 }
343 else
344 {
345 splt_detect_where_end_silence_begins(time, level, silence_was_found, must_flush, ssd, found_silence_points, error);
346 }
347
348 return SPLT_FALSE;
349 }
350
351