/* encode-ogg.c - grava PCM s16 mono (stdin) em Ogg Vorbis (stdout) com numero de serie fixo, para o arquivo sair * igual a cada execucao. Uso: encode-ogg < pcm > saida.ogg. libvorbisenc/libogg (BSD, xiph.org). */ #include #include #include int main(int argc, char **argv) { long rate = atol(argv[1]); float q = (float)atof(argv[2]); vorbis_info vi; vorbis_comment vc; vorbis_dsp_state vd; vorbis_block vb; ogg_stream_state os; ogg_page og; ogg_packet op, h1, h2, h3; vorbis_info_init(&vi); if (vorbis_encode_init_vbr(&vi, 1, rate, q)) return 1; vorbis_comment_init(&vc); vorbis_analysis_init(&vd, &vi); vorbis_block_init(&vd, &vb); ogg_stream_init(&os, 20261111); vorbis_analysis_headerout(&vd, &vc, &h1, &h2, &h3); ogg_stream_packetin(&os, &h1); ogg_stream_packetin(&os, &h2); ogg_stream_packetin(&os, &h3); while (ogg_stream_flush(&os, &og)) { fwrite(og.header, 1, og.header_len, stdout); fwrite(og.body, 1, og.body_len, stdout); } short buf[1024]; int eos = 0; while (!eos) { size_t n = fread(buf, 2, 1024, stdin); if (n == 0) vorbis_analysis_wrote(&vd, 0); else { float **b = vorbis_analysis_buffer(&vd, (int)n); for (size_t i = 0; i < n; i++) b[0][i] = buf[i] / 32768.f; vorbis_analysis_wrote(&vd, (int)n); } while (vorbis_analysis_blockout(&vd, &vb) == 1) { vorbis_analysis(&vb, NULL); vorbis_bitrate_addblock(&vb); while (vorbis_bitrate_flushpacket(&vd, &op)) { ogg_stream_packetin(&os, &op); while (!eos && ogg_stream_pageout(&os, &og)) { fwrite(og.header, 1, og.header_len, stdout); fwrite(og.body, 1, og.body_len, stdout); if (ogg_page_eos(&og)) eos = 1; } } } } return 0; }