Advertisement
Guest User

vala example for pulseaudio

a guest
May 22nd, 2011
429
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Vala 4.96 KB | None | 0 0
  1. // valac --pkg libpulse --pkg posix --pkg gtk+-2.0 --pkg libpulse-mainloop-glib pulse.vala
  2.  
  3. using PulseAudio;
  4.  
  5.  
  6. public class AudioDevice : GLib.Object {
  7.     private PulseAudio.GLibMainLoop loop;
  8.     private PulseAudio.Context context;
  9.     private Context.Flags cflags;
  10.     private PulseAudio.SampleSpec spec;
  11.     private PulseAudio.Stream.BufferAttr attr;
  12.     private double m_amp =0.3;
  13.     private double m_freq =500;
  14.     private ulong m_time=0;
  15.     private double twopi_over_sr;
  16.  
  17.     public AudioDevice () {
  18.         GLib.Object();
  19.     }
  20.  
  21.     construct {
  22.         this.spec = PulseAudio.SampleSpec() {
  23.             format = PulseAudio.SampleFormat.S16LE,
  24.                          channels = 2,
  25.                          rate =  44100
  26.         };
  27.         twopi_over_sr = (2.0 * Math.PI) / (double)spec.rate;
  28.     }
  29.  
  30.     public void start () {
  31.         this.loop = new PulseAudio.GLibMainLoop();
  32.         this.context = new PulseAudio.Context(loop.get_api(), null);
  33.         this.cflags = Context.Flags.NOFAIL;
  34.         this.context.set_state_callback(this.cstate_cb);
  35.  
  36.         // Connect the context
  37.         if (this.context.connect( null, this.cflags, null) < 0) {
  38.             print( "pa_context_connect() failed: %s\n", PulseAudio.strerror(context.errno()));
  39.         }
  40.  
  41.     }
  42.     public void stream_over_cb(Stream stream) {
  43.         print("AudioDevice: stream overflow...\n");
  44.     }
  45.     public void stream_under_cb(Stream stream) {
  46.         print("AudioDevice: stream underflow...\n");
  47.     }
  48.     public void write_cb(Stream stream, size_t nbytes) {
  49.         /*Stream.BufferAttr attr = stream.get_buffer_attr();
  50.         print("attr.maxlength:%u, tlength:%u, prebuf:%u, minreq:%u, fragsize:%u\n",
  51.                 attr.maxlength,
  52.                 attr.tlength,
  53.                 attr.prebuf,
  54.                 attr.minreq,
  55.                 attr.fragsize);
  56.             */
  57.         uint len = (uint)(nbytes / sizeof(int16));
  58.         int16[] data = new int16[ len ];
  59.  
  60.         // noise generator
  61.         //for (int i=0;i<len;i++) {
  62.         //  data[i]= (int16)Random.int_range (-32768, 32767);
  63.         //}
  64.  
  65.         // sine wave generator
  66.         uint samps=0;
  67.         for(uint i=0; i < len; i+=spec.channels) {
  68.             int16 val =  (int16)( 32767.0 *  m_amp * Math.sin( m_freq * m_time  * twopi_over_sr));
  69.             for(uint j=0; j < spec.channels;j++) {
  70.                 data[i+j] = val;
  71.                 samps++;
  72.             }
  73.             this.m_time++;
  74.         }
  75.         //print( "nbytes: %s, len:%s, data.length:%s, samps:%s\n", nbytes.to_string(), len.to_string(), data.length.to_string(), samps.to_string() );
  76.         //print("len:%u, data.length:%u, data.length*sizeof(int16):%u , sampbytess:%u\n---------\n", len, data.length, (uint)(sizeof(int16) * data.length), (uint)samps*(uint)sizeof(int16));
  77.         stream.write((void *)data, sizeof(int16) * data.length);
  78.         //stream.drain();
  79.         //stream.write(data, data.length);
  80.     }
  81.  
  82.     public void cstate_cb(Context context){
  83.         Context.State state = context.get_state();
  84.         if (state == Context.State.UNCONNECTED) { print("state UNCONNECTED\n"); }
  85.         if (state == Context.State.CONNECTING) { print("state CONNECTING\n"); }
  86.         if (state == Context.State.AUTHORIZING) { print("state AUTHORIZING,\n"); }
  87.         if (state == Context.State.SETTING_NAME) { print("state SETTING_NAME\n"); }
  88.         if (state == Context.State.READY) { print("state READY\n"); }
  89.         if (state == Context.State.FAILED) { print("state FAILED,\n"); }
  90.         if (state == Context.State.TERMINATED) { print("state TERMINATED\n"); }
  91.  
  92.         if (state == Context.State.READY) {
  93.             this.attr = PulseAudio.Stream.BufferAttr();
  94.             size_t fragment_size =0;
  95.             size_t n_fragments = 0;
  96.             Stream.Flags flags = Stream.Flags.INTERPOLATE_TIMING|Stream.Flags.AUTO_TIMING_UPDATE|Stream.Flags.EARLY_REQUESTS;
  97.  
  98.             PulseAudio.Stream stream = new PulseAudio.Stream(context, "", this.spec);
  99.             stream.set_write_callback(write_cb);
  100.             stream.set_overflow_callback(this.stream_over_cb);
  101.             stream.set_underflow_callback(this.stream_over_cb);
  102.  
  103.             size_t fs = spec.frame_size();
  104.             // Don't fix things more than necessary
  105.             if ((fragment_size % fs) == 0 && n_fragments >= 2 && fragment_size > 0){
  106.                 print("something went wrong\n");
  107.                 return ;
  108.             }
  109.             // Number of fragments set?
  110.             if (n_fragments < 2) {
  111.                 if (fragment_size > 0) {
  112.                     n_fragments = (spec.bytes_per_second() / 2 / fragment_size);
  113.                     if (n_fragments < 2)
  114.                         n_fragments = 2;
  115.                 } else
  116.                     n_fragments = 12;
  117.             }
  118.             // Fragment size set?
  119.             if (fragment_size <= 0) {
  120.                 fragment_size = spec.bytes_per_second() / 2 / n_fragments;
  121.                 if (fragment_size < 1024)
  122.                     fragment_size = 1024;
  123.             }
  124.  
  125.             print("fragment_size: %s, n_fragments: %s, fs: %s\n", fragment_size.to_string(), n_fragments.to_string(), fs.to_string());
  126.  
  127.             attr.maxlength = (uint32) (fragment_size * (n_fragments+1));
  128.             attr.tlength = (uint32) (fragment_size * n_fragments);
  129.             attr.prebuf = (uint32) fragment_size;
  130.             attr.minreq = (uint32) fragment_size;
  131.  
  132.             int tmp = stream.connect_playback(null, attr, flags, null,  null);
  133.             if (tmp < 0 ) {
  134.                 print("connect_playback returned %s\n", tmp.to_string());
  135.                 print(": pa_stream_connect_playback() failed: %s\n", PulseAudio.strerror(context.errno() ));
  136.             }
  137.         }
  138.     }
  139. }
  140.  
  141. int main (string[] args) {
  142.     Gtk.init (ref args);
  143.     AudioDevice adev = new AudioDevice();
  144.     adev.start();
  145.     Gtk.main ();
  146.     return 1;
  147. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement