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