diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/edje/src/bin/edje_multisense_convert.c | 329 |
1 files changed, 329 insertions, 0 deletions
diff --git a/libraries/edje/src/bin/edje_multisense_convert.c b/libraries/edje/src/bin/edje_multisense_convert.c new file mode 100644 index 0000000..d37d218 --- /dev/null +++ b/libraries/edje/src/bin/edje_multisense_convert.c | |||
@@ -0,0 +1,329 @@ | |||
1 | #include "edje_multisense_convert.h" | ||
2 | |||
3 | #ifdef HAVE_LIBSNDFILE | ||
4 | # define READBUF 1024 | ||
5 | # ifdef HAVE_VORBIS | ||
6 | # include <vorbis/vorbisenc.h> | ||
7 | # endif | ||
8 | |||
9 | # ifdef HAVE_LIBFLAC | ||
10 | # include <FLAC/metadata.h> | ||
11 | # include <FLAC/stream_encoder.h> | ||
12 | # endif | ||
13 | |||
14 | Edje_Sound_Encode * | ||
15 | _edje_multisense_encode(const char *filename, Edje_Sound_Sample *sample, double quality) | ||
16 | { | ||
17 | SF_INFO sfinfo; | ||
18 | SNDFILE* sfile; | ||
19 | Edje_Sound_Encode *enc_info; | ||
20 | |||
21 | enc_info = calloc(1, sizeof(Edje_Sound_Encode)); | ||
22 | if (!enc_info) | ||
23 | { | ||
24 | ERR("Error. while allocating memory to load file "); | ||
25 | exit(-1); | ||
26 | } | ||
27 | memset (&sfinfo, 0, sizeof (SF_INFO)); | ||
28 | |||
29 | enc_info->encoded = EINA_FALSE; | ||
30 | enc_info->comp_type = "RAW PCM"; | ||
31 | |||
32 | // Open wav file using sndfile | ||
33 | sfile = sf_open (filename, SFM_READ, &sfinfo); | ||
34 | if (!sfile) | ||
35 | { | ||
36 | ERR("Error. Unable to open audio file : %s", filename); | ||
37 | exit(-1); | ||
38 | } | ||
39 | |||
40 | if (!sf_format_check(&sfinfo)) | ||
41 | { | ||
42 | ERR("Error. Unknown file, not a valid audio file"); | ||
43 | exit(-1); | ||
44 | } | ||
45 | |||
46 | if (sample->compression == EDJE_SOUND_SOURCE_TYPE_INLINE_COMP) | ||
47 | { | ||
48 | sf_close(sfile); | ||
49 | #ifdef HAVE_LIBFLAC | ||
50 | //encode provided wav file to flac | ||
51 | enc_info->file = _edje_multisense_encode_to_flac((char *)filename, sfinfo); | ||
52 | if (enc_info->file) | ||
53 | { | ||
54 | enc_info->comp_type = "FLAC"; | ||
55 | enc_info->encoded = EINA_TRUE; | ||
56 | } | ||
57 | #else | ||
58 | WRN("WARNING: Unable to encode sound %s to FLAC compression", | ||
59 | sample->name); | ||
60 | #endif | ||
61 | } | ||
62 | else if (sample->compression == EDJE_SOUND_SOURCE_TYPE_INLINE_LOSSY) | ||
63 | { | ||
64 | sf_close(sfile); | ||
65 | #ifdef HAVE_VORBIS | ||
66 | //encode provided wav file to ogg-vorbis | ||
67 | enc_info->file = _edje_multisense_encode_to_ogg_vorbis((char *)filename, | ||
68 | quality, sfinfo); | ||
69 | if (enc_info->file) | ||
70 | { | ||
71 | enc_info->comp_type = "OGG-VORBIS"; | ||
72 | enc_info->encoded = EINA_TRUE; | ||
73 | } | ||
74 | #else | ||
75 | WRN("WARNING: Unable to encode sound %s to Ogg-Vorbis", | ||
76 | sample->name); | ||
77 | #endif | ||
78 | } | ||
79 | else | ||
80 | eina_stringshare_replace(&enc_info->file, filename); | ||
81 | return enc_info; | ||
82 | } | ||
83 | |||
84 | #ifdef HAVE_LIBFLAC | ||
85 | const char* | ||
86 | _edje_multisense_encode_to_flac(char *snd_path, SF_INFO sfinfo) | ||
87 | { | ||
88 | unsigned int total_samples = 0; /* can use a 32-bit number due to WAVE size limitations */ | ||
89 | FLAC__bool ok = 1; | ||
90 | FLAC__StreamEncoder *encoder = 0; | ||
91 | FLAC__StreamEncoderInitStatus init_status; | ||
92 | FLAC__StreamMetadata *metadata[2]; | ||
93 | FLAC__StreamMetadata_VorbisComment_Entry entry; | ||
94 | SNDFILE *sfile; | ||
95 | sf_count_t size; | ||
96 | char *tmp; | ||
97 | |||
98 | sfile = sf_open(snd_path, SFM_READ, &sfinfo); | ||
99 | if (!sfile) return NULL; | ||
100 | if (!sf_format_check(&sfinfo)) | ||
101 | { | ||
102 | sf_close(sfile); | ||
103 | return NULL; | ||
104 | } | ||
105 | size = sf_seek(sfile, 0, SEEK_END); | ||
106 | sf_seek(sfile, 0, SEEK_SET); | ||
107 | tmp = malloc(strlen(snd_path) + 1 + 5); | ||
108 | if (!tmp) | ||
109 | { | ||
110 | sf_close(sfile); | ||
111 | return NULL; | ||
112 | } | ||
113 | strcpy(tmp, snd_path); | ||
114 | snd_path = tmp; | ||
115 | strcat(snd_path, ".flac"); | ||
116 | |||
117 | total_samples = size; | ||
118 | |||
119 | /* allocate the encoder */ | ||
120 | if ((encoder = FLAC__stream_encoder_new()) == NULL) | ||
121 | { | ||
122 | ERR("ERROR: Creating FLAC encoder\n"); | ||
123 | free(snd_path); | ||
124 | sf_close(sfile); | ||
125 | return NULL; | ||
126 | } | ||
127 | |||
128 | /* Verify it's own encoded output. This will slow the encoding process. */ | ||
129 | ok &= FLAC__stream_encoder_set_verify(encoder, 1); | ||
130 | |||
131 | //Levels range from 0 (fastest, least compression) to 8 (slowest, most compression). | ||
132 | //A value larger than 8 will be treated as 8. | ||
133 | //5 is used for good compression and moderate compression/decompression speed. | ||
134 | ok &= FLAC__stream_encoder_set_compression_level(encoder, 5); | ||
135 | ok &= FLAC__stream_encoder_set_channels(encoder, sfinfo.channels); | ||
136 | ok &= FLAC__stream_encoder_set_bits_per_sample(encoder, 16); | ||
137 | ok &= FLAC__stream_encoder_set_sample_rate(encoder, sfinfo.samplerate); | ||
138 | ok &= FLAC__stream_encoder_set_total_samples_estimate(encoder, total_samples); | ||
139 | |||
140 | /* now add some metadata; we'll add some tags and a padding block */ | ||
141 | if (ok) | ||
142 | { | ||
143 | if ((metadata[0] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT)) == NULL | ||
144 | || (metadata[1] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)) == NULL | ||
145 | || !FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, "Encoder", "flac") | ||
146 | || !FLAC__metadata_object_vorbiscomment_append_comment(metadata[0], entry, 0)) | ||
147 | { | ||
148 | ERR("ERROR: out of memory error or tag error\n"); | ||
149 | ok = 0; | ||
150 | } | ||
151 | metadata[1]->length = 16; /* set the padding length */ | ||
152 | ok = FLAC__stream_encoder_set_metadata(encoder, metadata, 2); | ||
153 | } | ||
154 | |||
155 | /* initialize encoder */ | ||
156 | if (ok) | ||
157 | { | ||
158 | init_status = FLAC__stream_encoder_init_file(encoder, snd_path, NULL, | ||
159 | (void *)(long)(total_samples)); | ||
160 | if (init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) | ||
161 | { | ||
162 | ERR("ERROR: unable to initialize FLAC encoder: %s\n", | ||
163 | FLAC__StreamEncoderInitStatusString[init_status]); | ||
164 | ok = 0; | ||
165 | } | ||
166 | } | ||
167 | |||
168 | /* read blocks of samples from WAVE file and feed to encoder */ | ||
169 | while (ok) | ||
170 | { | ||
171 | FLAC__int32 readbuffer[READBUF * 2]; | ||
172 | sf_count_t count; | ||
173 | int i; | ||
174 | |||
175 | count = sf_readf_int(sfile, readbuffer, READBUF); | ||
176 | if (count <= 0) break; | ||
177 | for (i = 0; i < (count * sfinfo.channels); i++) | ||
178 | readbuffer[i] = readbuffer[i] >> 16; | ||
179 | ok = FLAC__stream_encoder_process_interleaved(encoder, readbuffer, | ||
180 | count); | ||
181 | } | ||
182 | |||
183 | FLAC__stream_encoder_finish(encoder); | ||
184 | /* now that encoding is finished, the metadata can be freed */ | ||
185 | FLAC__metadata_object_delete(metadata[0]); | ||
186 | FLAC__metadata_object_delete(metadata[1]); | ||
187 | |||
188 | FLAC__stream_encoder_delete(encoder); | ||
189 | sf_close(sfile); | ||
190 | return (snd_path); | ||
191 | } | ||
192 | #endif | ||
193 | |||
194 | #ifdef HAVE_VORBIS | ||
195 | const char * | ||
196 | _edje_multisense_encode_to_ogg_vorbis(char *snd_path, double quality, SF_INFO sfinfo) | ||
197 | { | ||
198 | ogg_stream_state os; /* take physical pages, weld into a logical stream of packets */ | ||
199 | ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */ | ||
200 | ogg_packet op; /* one raw packet of data for decode */ | ||
201 | vorbis_info vi; /* struct that stores all the static vorbis bitstream settings */ | ||
202 | vorbis_comment vc; /* struct that stores all the user comments */ | ||
203 | vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ | ||
204 | vorbis_block vb; /* local working space for packet->PCM decode */ | ||
205 | int eos = 0, ret; | ||
206 | char *tmp; | ||
207 | SNDFILE *sfile; | ||
208 | FILE *fout; | ||
209 | |||
210 | sfile = sf_open(snd_path, SFM_READ, &sfinfo); | ||
211 | if (!sfile) return NULL; | ||
212 | if (!sf_format_check(&sfinfo)) | ||
213 | { | ||
214 | sf_close(sfile); | ||
215 | return NULL; | ||
216 | } | ||
217 | tmp = malloc(strlen(snd_path) + 1 + 4); | ||
218 | if (!tmp) | ||
219 | { | ||
220 | sf_close(sfile); | ||
221 | return NULL; | ||
222 | } | ||
223 | strcpy(tmp, snd_path); | ||
224 | snd_path = tmp; | ||
225 | strcat(snd_path, ".ogg"); | ||
226 | fout = fopen(snd_path, "wb"); | ||
227 | if (!fout) | ||
228 | { | ||
229 | free(snd_path); | ||
230 | sf_close(sfile); | ||
231 | return NULL; | ||
232 | } | ||
233 | |||
234 | /********** Encode setup ************/ | ||
235 | vorbis_info_init(&vi); | ||
236 | ret = vorbis_encode_init(&vi, sfinfo.channels, sfinfo.samplerate, | ||
237 | -1, (long)(quality * 1000), -1); | ||
238 | if (ret == OV_EFAULT) printf("OV_EFAULT\n"); | ||
239 | if (ret == OV_EINVAL) printf("OV_EINVAL\n"); | ||
240 | if (ret == OV_EIMPL) printf("OV_EIMPL\n"); | ||
241 | |||
242 | if (ret) | ||
243 | { | ||
244 | fclose(fout); | ||
245 | free(snd_path); | ||
246 | sf_close(sfile); | ||
247 | return NULL; | ||
248 | } | ||
249 | |||
250 | /* add a comment */ | ||
251 | vorbis_comment_init(&vc); | ||
252 | vorbis_comment_add_tag(&vc, "", ""); | ||
253 | |||
254 | /* set up the analysis state and auxiliary encoding storage */ | ||
255 | vorbis_analysis_init(&vd, &vi); | ||
256 | vorbis_block_init(&vd, &vb); | ||
257 | |||
258 | srand(time(NULL)); | ||
259 | ogg_stream_init(&os, rand()); | ||
260 | |||
261 | ogg_packet header; | ||
262 | ogg_packet header_comm; | ||
263 | ogg_packet header_code; | ||
264 | |||
265 | vorbis_analysis_headerout(&vd, &vc, &header, &header_comm, &header_code); | ||
266 | ogg_stream_packetin(&os, &header); /* automatically placed in its own page */ | ||
267 | ogg_stream_packetin(&os, &header_comm); | ||
268 | ogg_stream_packetin(&os, &header_code); | ||
269 | |||
270 | while (!eos) | ||
271 | { | ||
272 | int result = ogg_stream_flush(&os, &og); | ||
273 | if (!result) break; | ||
274 | fwrite(og.header, 1, og.header_len, fout); | ||
275 | fwrite(og.body, 1, og.body_len, fout); | ||
276 | } | ||
277 | |||
278 | while (!eos) | ||
279 | { | ||
280 | int i, ch; | ||
281 | float readbuffer[READBUF * 2]; | ||
282 | sf_count_t count; | ||
283 | |||
284 | count = sf_readf_float(sfile, readbuffer, READBUF); | ||
285 | |||
286 | if (!count) | ||
287 | vorbis_analysis_wrote(&vd, 0); | ||
288 | else | ||
289 | { | ||
290 | float **buffer = vorbis_analysis_buffer(&vd, count); | ||
291 | |||
292 | /* uninterleave samples */ | ||
293 | for (i = 0; i < count; i++) | ||
294 | { | ||
295 | for (ch = 0; ch < sfinfo.channels; ch++) | ||
296 | buffer[ch][i]= readbuffer[(i * sfinfo.channels) + ch]; | ||
297 | } | ||
298 | vorbis_analysis_wrote(&vd, i); | ||
299 | } | ||
300 | while (vorbis_analysis_blockout(&vd, &vb) == 1) | ||
301 | { | ||
302 | vorbis_analysis(&vb, NULL); | ||
303 | vorbis_bitrate_addblock(&vb); | ||
304 | |||
305 | while (vorbis_bitrate_flushpacket(&vd, &op)) | ||
306 | { | ||
307 | ogg_stream_packetin(&os, &op); | ||
308 | while (!eos) | ||
309 | { | ||
310 | int result = ogg_stream_pageout(&os, &og); | ||
311 | if (!result) break; | ||
312 | fwrite(og.header, 1, og.header_len, fout); | ||
313 | fwrite(og.body, 1, og.body_len, fout); | ||
314 | if (ogg_page_eos(&og)) eos = 1; | ||
315 | } | ||
316 | } | ||
317 | } | ||
318 | } | ||
319 | ogg_stream_clear(&os); | ||
320 | vorbis_block_clear(&vb); | ||
321 | vorbis_dsp_clear(&vd); | ||
322 | vorbis_comment_clear(&vc); | ||
323 | vorbis_info_clear(&vi); | ||
324 | sf_close(sfile); | ||
325 | fclose (fout); | ||
326 | return snd_path; | ||
327 | } | ||
328 | #endif | ||
329 | #endif | ||