/dependencies/vorbis-java/src/main/java/org/xiph/VorbisEncoder.java

http://github.com/tulskiy/musique · Java · 187 lines · 103 code · 54 blank · 30 comment · 14 complexity · 03782d2bc771d4e41eddba2828c3f340 MD5 · raw file

  1. /*
  2. * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.
  3. * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS
  4. * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE
  5. * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.
  6. *
  7. * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002
  8. * by the Xiph.Org Foundation http://www.xiph.org/
  9. */
  10. package org.xiph;
  11. import org.xiph.libogg.ogg_packet;
  12. import org.xiph.libogg.ogg_page;
  13. import org.xiph.libogg.ogg_stream_state;
  14. import org.xiph.libvorbis.*;
  15. import java.io.FileInputStream;
  16. import java.io.FileOutputStream;
  17. public class VorbisEncoder {
  18. static vorbisenc encoder;
  19. static ogg_stream_state os; // take physical pages, weld into a logical stream of packets
  20. static ogg_page og; // one Ogg bitstream page. Vorbis packets are inside
  21. static ogg_packet op; // one raw packet of data for decode
  22. static vorbis_info vi; // struct that stores all the static vorbis bitstream settings
  23. static vorbis_comment vc; // struct that stores all the user comments
  24. static vorbis_dsp_state vd; // central working state for the packet->PCM decoder
  25. static vorbis_block vb; // local working space for packet->PCM decode
  26. static int READ = 1024;
  27. static byte[] readbuffer = new byte[READ * 4];
  28. static int page_count = 0;
  29. static int block_count = 0;
  30. /**
  31. * VorbisEncoder.java
  32. * <p/>
  33. * Usage:
  34. * java -cp VorbisEncoder <Input File[.wav]> <Output File[.ogg]>
  35. */
  36. public static void main(String[] args) {
  37. boolean eos = false;
  38. vi = new vorbis_info();
  39. encoder = new vorbisenc();
  40. if (!encoder.vorbis_encode_init_vbr(vi, 2, 44100, .3f)) {
  41. System.out.println("Failed to Initialize vorbisenc");
  42. return;
  43. }
  44. vc = new vorbis_comment();
  45. vc.vorbis_comment_add_tag("ENCODER", "Java Vorbis Encoder");
  46. vd = new vorbis_dsp_state();
  47. if (!vd.vorbis_analysis_init(vi)) {
  48. System.out.println("Failed to Initialize vorbis_dsp_state");
  49. return;
  50. }
  51. vb = new vorbis_block(vd);
  52. java.util.Random generator = new java.util.Random(); // need to randomize seed
  53. os = new ogg_stream_state(generator.nextInt(256));
  54. System.out.print("Writing header.");
  55. ogg_packet header = new ogg_packet();
  56. ogg_packet header_comm = new ogg_packet();
  57. ogg_packet header_code = new ogg_packet();
  58. vd.vorbis_analysis_headerout(vc, header, header_comm, header_code);
  59. os.ogg_stream_packetin(header); // automatically placed in its own page
  60. os.ogg_stream_packetin(header_comm);
  61. os.ogg_stream_packetin(header_code);
  62. og = new ogg_page();
  63. op = new ogg_packet();
  64. try {
  65. FileOutputStream fos = new FileOutputStream("testfiles/1.ogg");
  66. while (!eos) {
  67. if (!os.ogg_stream_flush(og))
  68. break;
  69. fos.write(og.header, 0, og.header_len);
  70. fos.write(og.body, 0, og.body_len);
  71. System.out.print(".");
  72. }
  73. System.out.print("Done.\n");
  74. FileInputStream fin = new FileInputStream("testfiles/mp3/sample.wav");
  75. fin.skip(44);
  76. System.out.print("Encoding.");
  77. while (!eos) {
  78. int i;
  79. int bytes = fin.read(readbuffer, 0, READ * 4); // stereo hardwired here
  80. int break_count = 0;
  81. if (bytes == 0) {
  82. // end of file. this can be done implicitly in the mainline,
  83. // but it's easier to see here in non-clever fashion.
  84. // Tell the library we're at end of stream so that it can handle
  85. // the last frame and mark end of stream in the output properly
  86. vd.vorbis_analysis_wrote(0);
  87. } else {
  88. // data to encode
  89. // expose the buffer to submit data
  90. float[][] buffer = vd.vorbis_analysis_buffer(READ);
  91. // uninterleave samples
  92. for (i = 0; i < bytes / 4; i++) {
  93. buffer[0][vd.pcm_current + i] = ((readbuffer[i * 4 + 1] << 8) | (0x00ff & (int) readbuffer[i * 4])) / 32768.f;
  94. buffer[1][vd.pcm_current + i] = ((readbuffer[i * 4 + 3] << 8) | (0x00ff & (int) readbuffer[i * 4 + 2])) / 32768.f;
  95. }
  96. // tell the library how much we actually submitted
  97. vd.vorbis_analysis_wrote(i);
  98. }
  99. // vorbis does some data preanalysis, then divvies up blocks for more involved
  100. // (potentially parallel) processing. Get a single block for encoding now
  101. while (vb.vorbis_analysis_blockout(vd)) {
  102. // analysis, assume we want to use bitrate management
  103. vb.vorbis_analysis(null);
  104. vb.vorbis_bitrate_addblock();
  105. while (vd.vorbis_bitrate_flushpacket(op)) {
  106. // weld the packet into the bitstream
  107. os.ogg_stream_packetin(op);
  108. // write out pages (if any)
  109. while (!eos) {
  110. if (!os.ogg_stream_pageout(og)) {
  111. break_count++;
  112. break;
  113. }
  114. fos.write(og.header, 0, og.header_len);
  115. fos.write(og.body, 0, og.body_len);
  116. // this could be set above, but for illustrative purposes, I do
  117. // it here (to show that vorbis does know where the stream ends)
  118. if (og.ogg_page_eos() > 0)
  119. eos = true;
  120. }
  121. }
  122. }
  123. System.out.print(".");
  124. }
  125. fin.close();
  126. fos.close();
  127. System.out.print("Done.\n");
  128. } catch (Exception e) {
  129. System.out.println("\n" + e);
  130. e.printStackTrace(System.out);
  131. }
  132. }
  133. }