5 #include "filevorbis.h"
14 #define _(String) gettext(String)
15 #define gettext_noop(String) String
16 #define N_(String) gettext_noop (String)
18 FileVorbis::FileVorbis(Asset *asset, File *file)
19 : FileBase(asset, file)
22 if(asset->format == FILE_UNKNOWN) asset->format = FILE_VORBIS;
23 asset->byte_order = 0;
26 FileVorbis::~FileVorbis()
31 void FileVorbis::get_parameters(BC_WindowBase *parent_window,
33 BC_WindowBase* &format_window,
39 VorbisConfigAudio *window = new VorbisConfigAudio(parent_window, asset);
40 format_window = window;
41 window->create_objects();
47 int FileVorbis::check_sig(Asset *asset)
49 FILE *fd = fopen(asset->path, "rb");
51 if(ov_open(fd, &vf, NULL, 0) < 0)
64 int FileVorbis::reset_parameters_derived()
67 bzero(&vf, sizeof(vf));
72 // Just create the Quicktime objects since this routine is also called
74 int FileVorbis::open_file(int rd, int wr)
80 //printf("FileVorbis::open_file 1\n");
83 //printf("FileVorbis::open_file 1\n");
84 if(!(fd = fopen(asset->path, "rb")))
86 printf("FileVorbis::open_file %s: %s\n", asset->path, strerror(errno));
91 //printf("FileVorbis::open_file 2 %p %p\n", fd, vf);
92 if(ov_open(fd, &vf, NULL, 0) < 0)
94 printf(_("FileVorbis::open_file %s: invalid bitstream.\n"), asset->path);
99 //printf("FileVorbis::open_file 1\n");
100 vorbis_info *vi = ov_info(&vf, -1);
101 asset->channels = vi->channels;
102 if(!asset->sample_rate)
103 asset->sample_rate = vi->rate;
104 //printf("FileVorbis::open_file 1\n");
105 asset->audio_length = ov_pcm_total(&vf,-1);
106 //printf("FileVorbis::open_file 1\n");
107 asset->audio_data = 1;
108 // printf("FileVorbis::open_file 1 %d %d %d\n",
110 // asset->sample_rate,
111 // asset->audio_length);
118 if(!(fd = fopen(asset->path, "wb")))
120 printf("FileVorbis::open_file %s: %s\n", asset->path, strerror(errno));
125 vorbis_info_init(&vi);
126 if(!asset->vorbis_vbr)
127 result = vorbis_encode_init(&vi,
130 asset->vorbis_max_bitrate,
131 asset->vorbis_bitrate,
132 asset->vorbis_min_bitrate);
135 result = vorbis_encode_setup_managed(&vi,
138 asset->vorbis_max_bitrate,
139 asset->vorbis_bitrate,
140 asset->vorbis_min_bitrate);
141 result |= vorbis_encode_ctl(&vi, OV_ECTL_RATEMANAGE_AVG, NULL);
142 result |= vorbis_encode_setup_init(&vi);
147 vorbis_analysis_init(&vd, &vi);
148 vorbis_block_init(&vd, &vb);
149 vorbis_comment_init(&vc);
151 ogg_stream_init(&os, rand());
154 ogg_packet header_comm;
155 ogg_packet header_code;
156 vorbis_analysis_headerout(&vd,
161 ogg_stream_packetin(&os,
163 ogg_stream_packetin(&os,
165 ogg_stream_packetin(&os,
170 int result = ogg_stream_flush(&os, &og);
171 if(result == 0) break;
172 fwrite(og.header, 1, og.header_len, fd);
173 fwrite(og.body, 1, og.body_len, fd);
179 //printf("FileVorbis::open_file 2\n");
183 #define FLUSH_VORBIS \
184 while(vorbis_analysis_blockout(&vd, &vb) == 1) \
186 vorbis_analysis(&vb, NULL); \
187 vorbis_bitrate_addblock(&vb); \
188 while(vorbis_bitrate_flushpacket(&vd, &op)) \
190 ogg_stream_packetin(&os, &op); \
194 int result = ogg_stream_pageout(&os, &og); \
196 fwrite(og.header, 1, og.header_len, fd); \
197 fwrite(og.body, 1, og.body_len, fd); \
198 if(ogg_page_eos(&og)) break; \
204 int FileVorbis::close_file()
210 vorbis_analysis_wrote(&vd, 0);
213 ogg_stream_clear(&os);
214 vorbis_block_clear(&vb);
215 vorbis_dsp_clear(&vd);
216 vorbis_comment_clear(&vc);
217 vorbis_info_clear(&vi);
223 // This also closes the file handle.
231 for(int i = 0; i < asset->channels; i++)
232 delete [] pcm_history[i];
233 delete [] pcm_history;
237 FileBase::close_file();
242 int FileVorbis::write_samples(double **buffer, int64_t len)
247 float **vorbis_buffer = vorbis_analysis_buffer(&vd, len);
248 for(int i = 0; i < asset->channels; i++)
250 float *output = vorbis_buffer[i];
251 double *input = buffer[i];
252 for(int j = 0; j < len; j++)
254 output[j] = input[j];
257 vorbis_analysis_wrote(&vd, len);
264 int FileVorbis::read_samples(double *buffer, int64_t len)
268 // printf("FileVorbis::read_samples 1 %d %d %d %d\n",
271 // file->current_sample,
273 float **vorbis_output;
275 int accumulation = 0;
276 //printf("FileVorbis::read_samples 1\n");
277 int decode_start = 0;
282 printf("FileVorbis::read_samples max samples=%d\n", HISTORY_MAX);
288 pcm_history = new double*[asset->channels];
289 for(int i = 0; i < asset->channels; i++)
290 pcm_history[i] = new double[HISTORY_MAX];
295 // Restart history. Don't bother shifting history back.
296 if(file->current_sample < history_start ||
297 file->current_sample > history_start + history_size)
300 history_start = file->current_sample;
301 decode_start = file->current_sample;
305 // Shift history forward to make room for new samples
306 if(file->current_sample + len > history_start + history_size)
308 if(file->current_sample + len > history_start + HISTORY_MAX)
310 int diff = file->current_sample + len - (history_start + HISTORY_MAX);
311 for(int i = 0; i < asset->channels; i++)
313 double *temp = pcm_history[i];
314 for(int j = 0; j < HISTORY_MAX - diff; j++)
316 temp[j] = temp[j + diff];
319 history_start += diff;
320 history_size -= diff;
324 decode_start = history_start + history_size;
325 decode_len = file->current_sample + len - (history_start + history_size);
329 // Fill history buffer
330 if(history_start + history_size != ov_pcm_tell(&vf))
332 //printf("FileVorbis::read_samples %d %d\n", history_start + history_size, ov_pcm_tell(&vf));
333 ov_pcm_seek(&vf, history_start + history_size);
336 while(accumulation < decode_len)
338 int result = ov_read_float(&vf,
340 decode_len - accumulation,
342 //printf("FileVorbis::read_samples 1 %d %d %d\n", result, len, accumulation);
345 for(int i = 0; i < asset->channels; i++)
347 double *output = pcm_history[i] + history_size;
348 float *input = vorbis_output[i];
349 for(int j = 0; j < result; j++)
350 output[j] = input[j];
352 history_size += result;
353 accumulation += result;
357 // printf("FileVorbis::read_samples 1 %d %d\n",
358 // file->current_sample,
361 double *input = pcm_history[file->current_channel] +
362 file->current_sample -
364 for(int i = 0; i < len; i++)
365 buffer[i] = input[i];
367 // printf("FileVorbis::read_samples 2 %d %d %d %d\n",
370 // file->current_sample,
385 VorbisConfigAudio::VorbisConfigAudio(BC_WindowBase *parent_window,
387 : BC_Window(PROGRAM_NAME ": Audio Compression",
388 parent_window->get_abs_cursor_x(),
389 parent_window->get_abs_cursor_y(),
398 this->parent_window = parent_window;
402 VorbisConfigAudio::~VorbisConfigAudio()
406 int VorbisConfigAudio::create_objects()
410 char string[BCTEXTLEN];
412 add_tool(fixed_bitrate = new VorbisFixedBitrate(x, y, this));
413 add_tool(variable_bitrate = new VorbisVariableBitrate(x1, y, this));
416 sprintf(string, "%d", asset->vorbis_min_bitrate);
417 add_tool(new BC_Title(x, y, _("Min bitrate:")));
418 add_tool(new VorbisMinBitrate(x1, y, this, string));
421 add_tool(new BC_Title(x, y, _("Avg bitrate:")));
422 sprintf(string, "%d", asset->vorbis_bitrate);
423 add_tool(new VorbisAvgBitrate(x1, y, this, string));
426 add_tool(new BC_Title(x, y, _("Max bitrate:")));
427 sprintf(string, "%d", asset->vorbis_max_bitrate);
428 add_tool(new VorbisMaxBitrate(x1, y, this, string));
431 add_subwindow(new BC_OKButton(this));
437 int VorbisConfigAudio::close_event()
447 VorbisFixedBitrate::VorbisFixedBitrate(int x, int y, VorbisConfigAudio *gui)
448 : BC_Radial(x, y, !gui->asset->vorbis_vbr, _("Fixed bitrate"))
452 int VorbisFixedBitrate::handle_event()
454 gui->asset->vorbis_vbr = 0;
455 gui->variable_bitrate->update(0);
459 VorbisVariableBitrate::VorbisVariableBitrate(int x, int y, VorbisConfigAudio *gui)
460 : BC_Radial(x, y, gui->asset->vorbis_vbr, _("Variable bitrate"))
464 int VorbisVariableBitrate::handle_event()
466 gui->asset->vorbis_vbr = 1;
467 gui->fixed_bitrate->update(0);
472 VorbisMinBitrate::VorbisMinBitrate(int x,
474 VorbisConfigAudio *gui,
476 : BC_TextBox(x, y, 180, 1, text)
480 int VorbisMinBitrate::handle_event()
482 gui->asset->vorbis_min_bitrate = atol(get_text());
488 VorbisMaxBitrate::VorbisMaxBitrate(int x,
490 VorbisConfigAudio *gui,
492 : BC_TextBox(x, y, 180, 1, text)
496 int VorbisMaxBitrate::handle_event()
498 gui->asset->vorbis_max_bitrate = atol(get_text());
504 VorbisAvgBitrate::VorbisAvgBitrate(int x, int y, VorbisConfigAudio *gui, char *text)
505 : BC_TextBox(x, y, 180, 1, text)
509 int VorbisAvgBitrate::handle_event()
511 gui->asset->vorbis_bitrate = atol(get_text());