PageRenderTime 3516ms CodeModel.GetById 34ms RepoModel.GetById 1ms app.codeStats 1ms

/source/external/mpg123-1.25.6/ports/MSVC++/2008clr/examples/feedseekclr/Program.cs

https://bitbucket.org/liflg/library-sdl2-mixer
C# | 331 lines | 219 code | 81 blank | 31 comment | 53 complexity | 4b3d79c687eb7a1a14e9a3cd598a635a MD5 | raw file
  1. /*
  2. feedseekclr: test program for mpg123clr, showing how to use fuzzy seeking in feeder mode
  3. copyright 2009 by the mpg123 project - free software under the terms of the LGPL 2.1
  4. see COPYING and AUTHORS files in distribution or http://mpg123.org
  5. based on feedseek.c example for libmpg123.
  6. Comment (Malcolm Boczek)
  7. this CLR example has been written to allow easy comparison to the original feedseek.c example
  8. and uses some constructs that would not normally be used in a C# environment,
  9. eg: byte[]/ASCII text, Marshal.Copy, static fields, lots of casts etc.
  10. */
  11. /*
  12. 1.9.0.0 24-Sep-09 Function names harmonized with libmpg123 (mb)
  13. */
  14. using System;
  15. using System.Collections.Generic;
  16. using System.Linq;
  17. using System.Text;
  18. using System.IO;
  19. using System.Runtime.InteropServices;
  20. using mpg123clr;
  21. namespace feedseekclr
  22. {
  23. class Program
  24. {
  25. const int WAVE_FORMAT_PCM = 0x0001;
  26. const int WAVE_FORMAT_IEEE_FLOAT = 0x0003;
  27. static BinaryWriter _out;
  28. static long totaloffset, dataoffset;
  29. static int rate;
  30. static mpg123clr.mpg.channelcount channels;
  31. static mpg123clr.mpg.enc enc;
  32. static short bitspersample, wavformat;
  33. // write wav header
  34. static void initwav()
  35. {
  36. uint tmp32 = 0;
  37. ushort tmp16 = 0;
  38. byte[] rifftxt = new byte[] { (byte)'R', (byte)'I', (byte)'F', (byte)'F' };
  39. byte[] wavetxt = new byte[] { (byte)'W', (byte)'A', (byte)'V', (byte)'E' };
  40. byte[] fmttxt = new byte[] { (byte)'f', (byte)'m', (byte)'t', (byte)' ' };
  41. byte[] datatxt = new byte[] { (byte)'d', (byte)'a', (byte)'t', (byte)'a' };
  42. _out.Write(rifftxt);
  43. totaloffset = _out.BaseStream.Position;
  44. _out.Write(tmp32); // total size
  45. _out.Write(wavetxt);
  46. _out.Write(fmttxt);
  47. tmp32 = 16;
  48. _out.Write(tmp32); // format length
  49. tmp16 = (ushort)wavformat;
  50. _out.Write(tmp16); // format
  51. tmp16 = (ushort)channels;
  52. _out.Write(tmp16); // channels
  53. tmp32 = (uint)rate;
  54. _out.Write(tmp32); // sample rate
  55. tmp32 = (uint) (rate * bitspersample / 8 * (int)channels);
  56. _out.Write(tmp32); // bytes / second
  57. tmp16 = (ushort)(bitspersample / 8 * (int)channels); // float 16 or signed int 16
  58. _out.Write(tmp16); // block align
  59. tmp16 = (ushort)bitspersample;
  60. _out.Write(tmp16); // bits per sample
  61. _out.Write(datatxt);
  62. tmp32 = 0;
  63. dataoffset = _out.BaseStream.Position;
  64. _out.Write(tmp32); // data length
  65. }
  66. // rewrite wav header with final length infos
  67. static void closewav()
  68. {
  69. uint tmp32 = 0;
  70. // ushort tmp16 = 0;
  71. int total = (int)_out.BaseStream.Position;
  72. _out.Seek((int)totaloffset, SeekOrigin.Begin);
  73. tmp32 = (uint)(total - (totaloffset + 4));
  74. _out.Write(tmp32);
  75. _out.Seek((int)dataoffset, SeekOrigin.Begin);
  76. tmp32 = (uint)(total - (dataoffset + 4));
  77. _out.Write(tmp32);
  78. }
  79. // determine correct wav format and bits per sample
  80. // from mpg123 enc value
  81. static void initwavformat()
  82. {
  83. if ((enc & mpg123clr.mpg.enc.enc_float_64) != 0)
  84. {
  85. bitspersample = 64;
  86. wavformat = WAVE_FORMAT_IEEE_FLOAT;
  87. }
  88. else if ((enc & mpg123clr.mpg.enc.enc_float_32) != 0)
  89. {
  90. bitspersample = 32;
  91. wavformat = WAVE_FORMAT_IEEE_FLOAT;
  92. }
  93. else if ((enc & mpg123clr.mpg.enc.enc_16) != 0)
  94. {
  95. bitspersample = 16;
  96. wavformat = WAVE_FORMAT_PCM;
  97. }
  98. else
  99. {
  100. bitspersample = 8;
  101. wavformat = WAVE_FORMAT_PCM;
  102. }
  103. }
  104. static void Main(string[] args)
  105. {
  106. const long INBUFF = 16384 * 2 * 2;
  107. int ret;
  108. mpg123clr.mpg.ErrorCode state;
  109. long inoffset,inc = 0;
  110. long outc = 0;
  111. byte[] buf = new byte[INBUFF];
  112. if (args.Length < 2)
  113. {
  114. Console.WriteLine("Please supply in and out filenames\n");
  115. Console.WriteLine("Press any key to exit:");
  116. while (Console.Read() == 0) ;
  117. return;
  118. }
  119. mpg123clr.mpg.ErrorCode err;
  120. err = mpg123.mpg123_init();
  121. mpg123 mp = new mpg123();
  122. err = mp.mpg123_new();
  123. if (err != mpg123clr.mpg.ErrorCode.ok)
  124. {
  125. Console.WriteLine("Unable to create mpg123 handle: " + mpg123error.mpg123_plain_strerror(err));
  126. Console.WriteLine("Press any key to exit:");
  127. while (Console.Read() == 0) ;
  128. return;
  129. }
  130. mp.mpg123_param(mpg123clr.mpg.parms.verbose, 4, 0);
  131. err = mp.mpg123_param(mpg123clr.mpg.parms.flags,
  132. (int) (mpg123clr.mpg.param_flags.fuzzy |
  133. mpg123clr.mpg.param_flags.seekbuffer |
  134. mpg123clr.mpg.param_flags.gapless), 0);
  135. if (err != mpg123clr.mpg.ErrorCode.ok)
  136. {
  137. Console.WriteLine("Unable to set library options: " + mp.mpg123_strerror());
  138. Console.WriteLine("Press any key to exit:");
  139. while (Console.Read() == 0) ;
  140. return;
  141. }
  142. // Let the seek index auto-grow and contain an entry for every frame
  143. err = mp.mpg123_param(mpg123clr.mpg.parms.index_size, -1, 0);
  144. if (err != mpg123clr.mpg.ErrorCode.ok)
  145. {
  146. Console.WriteLine("Unable to set index size: " + mp.mpg123_strerror());
  147. Console.WriteLine("Press any key to exit:");
  148. while (Console.Read() == 0) ;
  149. return;
  150. }
  151. // Use float output formats only
  152. err = mp.mpg123_format_none();
  153. if (err != mpg123clr.mpg.ErrorCode.ok)
  154. {
  155. Console.WriteLine("Unable to disable all output formats: " + mp.mpg123_strerror());
  156. Console.WriteLine("Press any key to exit:");
  157. while (Console.Read() == 0) ;
  158. return;
  159. }
  160. int[] rates = mp.mpg123_rates();
  161. foreach (int rate in rates)
  162. {
  163. err = mp.mpg123_format(rate, mpg123clr.mpg.channelcount.both, mpg123clr.mpg.enc.enc_float_32);
  164. if (err != mpg123clr.mpg.ErrorCode.ok)
  165. {
  166. Console.WriteLine("Unable to set float output formats: " + mp.mpg123_strerror());
  167. Console.WriteLine("Press any key to exit:");
  168. while (Console.Read() == 0) ;
  169. return;
  170. }
  171. }
  172. err = mp.mpg123_open_feed();
  173. if (err != mpg123clr.mpg.ErrorCode.ok)
  174. {
  175. Console.WriteLine("Unable to open feed: " + mp.mpg123_strerror());
  176. Console.WriteLine("Press any key to exit:");
  177. while (Console.Read() == 0) ;
  178. return;
  179. }
  180. string filename = args[0];
  181. BinaryReader _in = new BinaryReader(File.Open(filename, FileMode.Open));
  182. _out = new BinaryWriter(File.Open(args[1], FileMode.Create));
  183. while ((ret = (int)(mp.mpg123_feedseek(95000, SeekOrigin.Begin, out inoffset))) == (int)mpg123clr.mpg.ErrorCode.need_more) // equiv to mpg123_feedseek
  184. {
  185. buf = _in.ReadBytes((int)INBUFF);
  186. if (buf.Length <= 0) break;
  187. inc += buf.Length;
  188. state = mp.mpg123_feed(buf, (uint)buf.Length);
  189. if (state == mpg123clr.mpg.ErrorCode.err)
  190. {
  191. Console.WriteLine("Feed error: " + mp.mpg123_strerror());
  192. Console.WriteLine("Press any key to exit:");
  193. while (Console.Read() == 0) ;
  194. return;
  195. }
  196. }
  197. _in.BaseStream.Seek(inoffset, SeekOrigin.Begin);
  198. while (true)
  199. {
  200. buf = _in.ReadBytes((int)INBUFF);
  201. if (buf.Length <= 0) break;
  202. inc += buf.Length;
  203. err = mp.mpg123_feed(buf, (uint)buf.Length);
  204. int num;
  205. uint bytes;
  206. IntPtr audio;
  207. while (err != mpg123clr.mpg.ErrorCode.err && err != mpg123clr.mpg.ErrorCode.need_more)
  208. {
  209. err = mp.mpg123_decode_frame(out num, out audio, out bytes);
  210. if (err == mpg123clr.mpg.ErrorCode.new_format)
  211. {
  212. mp.mpg123_getformat(out rate, out channels, out enc);
  213. initwavformat();
  214. initwav();
  215. }
  216. // (Surprisingly?) even though it does a Marshal.Copy it's as efficient as the pointer example below!!!
  217. if (bytes > 0)
  218. {
  219. byte[] outbuf = new byte[bytes];
  220. Marshal.Copy(audio, outbuf, 0, (int)bytes);
  221. _out.Write(outbuf, 0, (int)bytes);
  222. }
  223. // Alternative example of direct usage of audio data via pointers - note it needs "unsafe"
  224. // and I'm fairly sure pointers should be "fixed" first
  225. // if (bytes > 0)
  226. // unsafe{
  227. // byte* p = (byte*)audio;
  228. // for (int ii = 0; ii < bytes; ii++)
  229. // _out.Write(*p++);
  230. // }
  231. outc += bytes;
  232. }
  233. if (err == mpg123clr.mpg.ErrorCode.err)
  234. {
  235. Console.WriteLine("Error: " + mp.mpg123_strerror());
  236. break;
  237. }
  238. }
  239. Console.WriteLine("Finished");
  240. closewav();
  241. _out.Close();
  242. _in.Close();
  243. mp.mpg123_delete();
  244. mp.Dispose();
  245. mpg123.mpg123_exit();
  246. }
  247. }
  248. }