Guest User

Daniel Barlow

a guest
Jan 22nd, 2010
960
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/ruby
  2.  
  3. # ruby FFI gem rocks!  http://rdoc.info/projects/ffi/ffi
  4.  
  5. # Please note this is experimental code and has awful APIs.  
  6. # Learn from it (if you can find anything to learn), but please do not use
  7. # it as-is
  8.  
  9. require 'rubygems'
  10. require 'ffi'
  11.  
  12. module PortAudio
  13.   extend FFI::Library
  14.   ffi_lib 'portaudio'
  15.  
  16.   module Format
  17.     Int16=0x8
  18.   end
  19.   attach_function :Pa_Initialize, [], :int # typedef int PaError
  20.   attach_function :Pa_GetVersion, [], :int
  21.   attach_function :Pa_GetErrorText, [:int], :string
  22.   attach_function :Pa_OpenDefaultStream, [:pointer,:int,:int,:ulong,:double,:ulong,:pointer,:pointer], :int
  23.   attach_function :Pa_StartStream, [:pointer], :int
  24.   attach_function :Pa_IsStreamActive, [:pointer], :int
  25.   attach_function :Pa_WriteStream, [:pointer,:pointer,:ulong], :int
  26.   attach_function :Pa_GetStreamWriteAvailable, [:pointer], :long
  27.   def self.or_raise
  28.     ret=yield
  29.     if(ret<0) then
  30.       text=Pa_GetErrorText(ret)
  31.       raise "PortAudio error #{ret}, #{text}"
  32.     end
  33.     ret
  34.   end
  35.   def self.initialize
  36.     init=self.Pa_Initialize
  37.     if init!=0 then
  38.       # how do we test this path?
  39.       text=Pa_GetErrorText(init)
  40.       raise "Pa_Initialize returned #{init}, #{text}"
  41.     end
  42.     v=PortAudio.Pa_GetVersion
  43.     if v<1899 then
  44.       raise "PortAudio version #{v} is too old: need 1899 or newer"
  45.     end
  46.   end
  47.   def self.open_default_stream(n_input_channels,n_output_channels,
  48.                                format,rate,frames_per_buffer)
  49.     @out=FFI::MemoryPointer.new :pointer
  50.     puts    @out.inspect
  51.     Pa_OpenDefaultStream(@out,n_input_channels,n_output_channels,
  52.                          format,rate,frames_per_buffer,nil,nil)
  53.     return @out.get_pointer(0)
  54.   end
  55.   def self.start_stream(stream)
  56.     self.or_raise {
  57.       PortAudio.Pa_StartStream(stream)
  58.     }
  59.   end
  60.   def self.stream_write_available(stream)
  61.     self.or_raise {
  62.       self.Pa_GetStreamWriteAvailable(stream)
  63.     }
  64.   end
  65. end
  66.  
  67.  
  68. buf=nil
  69. file='/big/media/Music/from_usb_stick/Hot Chip/The Warning/Over and Over.mp3'
  70. open("|/usr/local/bin/mplayer -quiet -really-quiet -vc null -vo null -ao pcm:nowaveheader:file=/dev/stdout:fast '#{file}'") { |f|
  71.   buf=f.read
  72. }
  73. #buf=buf.slice(0,16000)
  74. puts buf.length
  75.  
  76. PortAudio.initialize
  77. stream=PortAudio.open_default_stream(0,2,PortAudio::Format::Int16,44100,256);
  78. puts "stream is #{stream}"
  79. puts PortAudio.Pa_IsStreamActive(stream)
  80. PortAudio.start_stream(stream)
  81. puts PortAudio.Pa_IsStreamActive(stream)
  82. off=0
  83. while off<buf.length do
  84.   frames=PortAudio.stream_write_available(stream)
  85.   puts "off #{off} frames #{frames}"
  86.   PortAudio.Pa_WriteStream(stream,buf.slice(off,frames*4),frames)
  87.   off+=frames*4
  88. end
  89.  
RAW Paste Data