5 #include "filevorbis.h"
15 FileVorbis::FileVorbis(Asset *asset, File *file)
16 : FileBase(asset, file)
19 if(asset->format == FILE_UNKNOWN) asset->format = FILE_VORBIS;
20 asset->byte_order = 0;
23 FileVorbis::~FileVorbis()
28 void FileVorbis::get_parameters(BC_WindowBase *parent_window,
30 BC_WindowBase* &format_window,
36 VorbisConfigAudio *window = new VorbisConfigAudio(parent_window, asset);
37 format_window = window;
38 window->create_objects();
44 int FileVorbis::check_sig(Asset *asset)
46 FILE *fd = fopen(asset->path, "rb");
49 // Test for Quicktime since OGG misinterprets it
50 fseek(fd, 4, SEEK_SET);
52 fread(data, 4, 1, fd);
62 fseek(fd, 0, SEEK_SET);
64 if(ov_open(fd, &vf, NULL, 0) < 0)
66 // OGG failed. Close file handle manually.
78 int FileVorbis::reset_parameters_derived()
81 bzero(&vf, sizeof(vf));
86 // Just create the Quicktime objects since this routine is also called
88 int FileVorbis::open_file(int rd, int wr)
94 //printf("FileVorbis::open_file 1\n");
97 //printf("FileVorbis::open_file 1\n");
98 if(!(fd = fopen(asset->path, "rb")))
100 printf("FileVorbis::open_file %s: %s\n", asset->path, strerror(errno));
105 //printf("FileVorbis::open_file 2 %p %p\n", fd, vf);
106 if(ov_open(fd, &vf, NULL, 0) < 0)
108 printf(_("FileVorbis::open_file %s: invalid bitstream.\n"), asset->path);
113 //printf("FileVorbis::open_file 1\n");
114 vorbis_info *vi = ov_info(&vf, -1);
115 asset->channels = vi->channels;
116 if(!asset->sample_rate)
117 asset->sample_rate = vi->rate;
118 //printf("FileVorbis::open_file 1\n");
119 asset->audio_length = ov_pcm_total(&vf,-1);
120 //printf("FileVorbis::open_file 1\n");
121 asset->audio_data = 1;
122 // printf("FileVorbis::open_file 1 %d %d %d\n",
124 // asset->sample_rate,
125 // asset->audio_length);
132 if(!(fd = fopen(asset->path, "wb")))
134 printf("FileVorbis::open_file %s: %s\n", asset->path, strerror(errno));
139 vorbis_info_init(&vi);
140 if(!asset->vorbis_vbr)
141 result = vorbis_encode_init(&vi,
144 asset->vorbis_max_bitrate,
145 asset->vorbis_bitrate,
146 asset->vorbis_min_bitrate);
149 result = vorbis_encode_setup_managed(&vi,
152 asset->vorbis_max_bitrate,
153 asset->vorbis_bitrate,
154 asset->vorbis_min_bitrate);
155 result |= vorbis_encode_ctl(&vi, OV_ECTL_RATEMANAGE_AVG, NULL);
156 result |= vorbis_encode_setup_init(&vi);
161 vorbis_analysis_init(&vd, &vi);
162 vorbis_block_init(&vd, &vb);
163 vorbis_comment_init(&vc);
165 ogg_stream_init(&os, rand());
168 ogg_packet header_comm;
169 ogg_packet header_code;
170 vorbis_analysis_headerout(&vd,
175 ogg_stream_packetin(&os,
177 ogg_stream_packetin(&os,
179 ogg_stream_packetin(&os,
184 int result = ogg_stream_flush(&os, &og);
185 if(result == 0) break;
186 fwrite(og.header, 1, og.header_len, fd);
187 fwrite(og.body, 1, og.body_len, fd);
193 //printf("FileVorbis::open_file 2\n");
197 #define FLUSH_VORBIS \
198 while(vorbis_analysis_blockout(&vd, &vb) == 1) \
200 vorbis_analysis(&vb, NULL); \
201 vorbis_bitrate_addblock(&vb); \
202 while(vorbis_bitrate_flushpacket(&vd, &op)) \
204 ogg_stream_packetin(&os, &op); \
208 int result = ogg_stream_pageout(&os, &og); \
210 fwrite(og.header, 1, og.header_len, fd); \
211 fwrite(og.body, 1, og.body_len, fd); \
212 if(ogg_page_eos(&og)) break; \
218 int FileVorbis::close_file()
224 vorbis_analysis_wrote(&vd, 0);
227 ogg_stream_clear(&os);
228 vorbis_block_clear(&vb);
229 vorbis_dsp_clear(&vd);
230 vorbis_comment_clear(&vc);
231 vorbis_info_clear(&vi);
237 // This also closes the file handle.
245 for(int i = 0; i < asset->channels; i++)
246 delete [] pcm_history[i];
247 delete [] pcm_history;
251 FileBase::close_file();
256 int FileVorbis::write_samples(double **buffer, int64_t len)
261 float **vorbis_buffer = vorbis_analysis_buffer(&vd, len);
262 for(int i = 0; i < asset->channels; i++)
264 float *output = vorbis_buffer[i];
265 double *input = buffer[i];
266 for(int j = 0; j < len; j++)
268 output[j] = input[j];
271 vorbis_analysis_wrote(&vd, len);
278 int FileVorbis::read_samples(double *buffer, int64_t len)
282 // printf("FileVorbis::read_samples 1 %d %d %d %d\n",
285 // file->current_sample,
287 float **vorbis_output;
289 int accumulation = 0;
290 //printf("FileVorbis::read_samples 1\n");
291 int decode_start = 0;
296 printf("FileVorbis::read_samples max samples=%d\n", HISTORY_MAX);
302 pcm_history = new double*[asset->channels];
303 for(int i = 0; i < asset->channels; i++)
304 pcm_history[i] = new double[HISTORY_MAX];
309 // Restart history. Don't bother shifting history back.
310 if(file->current_sample < history_start ||
311 file->current_sample > history_start + history_size)
314 history_start = file->current_sample;
315 decode_start = file->current_sample;
319 // Shift history forward to make room for new samples
320 if(file->current_sample + len > history_start + history_size)
322 if(file->current_sample + len > history_start + HISTORY_MAX)
324 int diff = file->current_sample + len - (history_start + HISTORY_MAX);
325 for(int i = 0; i < asset->channels; i++)
327 double *temp = pcm_history[i];
328 for(int j = 0; j < HISTORY_MAX - diff; j++)
330 temp[j] = temp[j + diff];
333 history_start += diff;
334 history_size -= diff;
338 decode_start = history_start + history_size;
339 decode_len = file->current_sample + len - (history_start + history_size);
343 // Fill history buffer
344 if(history_start + history_size != ov_pcm_tell(&vf))
346 //printf("FileVorbis::read_samples %d %d\n", history_start + history_size, ov_pcm_tell(&vf));
347 ov_pcm_seek(&vf, history_start + history_size);
350 while(accumulation < decode_len)
352 int result = ov_read_float(&vf,
354 decode_len - accumulation,
356 //printf("FileVorbis::read_samples 1 %d %d %d\n", result, len, accumulation);
359 for(int i = 0; i < asset->channels; i++)
361 double *output = pcm_history[i] + history_size;
362 float *input = vorbis_output[i];
363 for(int j = 0; j < result; j++)
364 output[j] = input[j];
366 history_size += result;
367 accumulation += result;
371 // printf("FileVorbis::read_samples 1 %d %d\n",
372 // file->current_sample,
375 double *input = pcm_history[file->current_channel] +
376 file->current_sample -
378 for(int i = 0; i < len; i++)
379 buffer[i] = input[i];
381 // printf("FileVorbis::read_samples 2 %d %d %d %d\n",
384 // file->current_sample,
399 VorbisConfigAudio::VorbisConfigAudio(BC_WindowBase *parent_window,
401 : BC_Window(PROGRAM_NAME ": Audio Compression",
402 parent_window->get_abs_cursor_x(1),
403 parent_window->get_abs_cursor_y(1),
412 this->parent_window = parent_window;
416 VorbisConfigAudio::~VorbisConfigAudio()
420 int VorbisConfigAudio::create_objects()
424 char string[BCTEXTLEN];
426 add_tool(fixed_bitrate = new VorbisFixedBitrate(x, y, this));
427 add_tool(variable_bitrate = new VorbisVariableBitrate(x1, y, this));
430 sprintf(string, "%d", asset->vorbis_min_bitrate);
431 add_tool(new BC_Title(x, y, _("Min bitrate:")));
432 add_tool(new VorbisMinBitrate(x1, y, this, string));
435 add_tool(new BC_Title(x, y, _("Avg bitrate:")));
436 sprintf(string, "%d", asset->vorbis_bitrate);
437 add_tool(new VorbisAvgBitrate(x1, y, this, string));
440 add_tool(new BC_Title(x, y, _("Max bitrate:")));
441 sprintf(string, "%d", asset->vorbis_max_bitrate);
442 add_tool(new VorbisMaxBitrate(x1, y, this, string));
445 add_subwindow(new BC_OKButton(this));
451 int VorbisConfigAudio::close_event()
461 VorbisFixedBitrate::VorbisFixedBitrate(int x, int y, VorbisConfigAudio *gui)
462 : BC_Radial(x, y, !gui->asset->vorbis_vbr, _("Fixed bitrate"))
466 int VorbisFixedBitrate::handle_event()
468 gui->asset->vorbis_vbr = 0;
469 gui->variable_bitrate->update(0);
473 VorbisVariableBitrate::VorbisVariableBitrate(int x, int y, VorbisConfigAudio *gui)
474 : BC_Radial(x, y, gui->asset->vorbis_vbr, _("Variable bitrate"))
478 int VorbisVariableBitrate::handle_event()
480 gui->asset->vorbis_vbr = 1;
481 gui->fixed_bitrate->update(0);
486 VorbisMinBitrate::VorbisMinBitrate(int x,
488 VorbisConfigAudio *gui,
490 : BC_TextBox(x, y, 180, 1, text)
494 int VorbisMinBitrate::handle_event()
496 gui->asset->vorbis_min_bitrate = atol(get_text());
502 VorbisMaxBitrate::VorbisMaxBitrate(int x,
504 VorbisConfigAudio *gui,
506 : BC_TextBox(x, y, 180, 1, text)
510 int VorbisMaxBitrate::handle_event()
512 gui->asset->vorbis_max_bitrate = atol(get_text());
518 VorbisAvgBitrate::VorbisAvgBitrate(int x, int y, VorbisConfigAudio *gui, char *text)
519 : BC_TextBox(x, y, 180, 1, text)
523 int VorbisAvgBitrate::handle_event()
525 gui->asset->vorbis_bitrate = atol(get_text());