<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>ext/ruby/test_load.rb</filename>
    </added>
    <added>
      <filename>sounds/dart.blu</filename>
    </added>
    <added>
      <filename>sounds/error.blu</filename>
    </added>
    <added>
      <filename>sounds/ice.blu</filename>
    </added>
    <added>
      <filename>sounds/jump.blu</filename>
    </added>
    <added>
      <filename>sounds/pogo.blu</filename>
    </added>
    <added>
      <filename>sounds/stun.blu</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -88,5 +88,7 @@ bloopsatrack *bloops_track(bloops *, bloopsaphone *, char *, int);
 bloopsatrack *bloops_track2(bloops *, bloopsaphone *, char *);
 char *bloops_track_str(bloopsatrack *);
 float bloops_note_freq(char, int);
+bloopsaphone *bloops_sound_file(bloops *, char *);
+char *bloops_sound_str(bloops *, bloopsaphone *);
  
 #endif</diff>
      <filename>c/bloopsaphone.h</filename>
    </modified>
    <modified>
      <diff>@@ -7,6 +7,8 @@
 #include &lt;stdio.h&gt;
 #include &lt;stdlib.h&gt;
 #include &lt;string.h&gt;
+#include &lt;math.h&gt;
+#include &lt;sys/stat.h&gt;
 #include &quot;bloopsaphone.h&quot;
 
 #define ATOI(X,N) ({ \
@@ -283,3 +285,163 @@ bloops_note_freq(char note, int octave)
 
   return 0.0;
 }
+
+#define KEY(name) key = (void *)&amp;P-&gt;name
+
+%%{
+  machine bloopserial;
+
+  action ival {
+    ival = ATOI(ts, p - ts);
+  }
+
+  action fval1 {
+    fval = ATOI(ts, p - ts) * 1.0f;
+  }
+
+  action fval2 {
+    fval = ATOI(pf, p - pf) * pow(0.1f, p - pf);
+  }
+
+  dec = [0-9]+ %fval1 &quot;.&quot; %{ pf = p; } [0-9]+ %fval2;
+  float = (&quot;-&quot; dec %{ fval *= -1.0f; } | dec);
+  key = &quot;volume&quot; %{ KEY(volume); } |
+        &quot;arp&quot; %{ KEY(arp); } |
+        &quot;aspeed&quot; %{ KEY(aspeed); } |
+        &quot;attack&quot; %{ KEY(attack); } |
+        &quot;decay&quot; %{ KEY(decay); } |
+        &quot;dslide&quot; %{ KEY(dslide); } |
+        &quot;freq&quot; %{ KEY(freq); } |
+        &quot;hpf&quot; %{ KEY(hpf); } |
+        &quot;hsweep&quot; %{ KEY(hsweep); } |
+        &quot;limit&quot; %{ KEY(limit); } |
+        &quot;lpf&quot; %{ KEY(lpf); } |
+        &quot;lsweep&quot; %{ KEY(lsweep); } |
+        &quot;phase&quot; %{ KEY(phase); } |
+        &quot;psweep&quot; %{ KEY(psweep); } |
+        &quot;repeat&quot; %{ KEY(repeat); } |
+        &quot;resonance&quot; %{ KEY(resonance); } |
+        &quot;slide&quot; %{ KEY(slide); } |
+        &quot;square&quot; %{ KEY(square); } |
+        &quot;sustain&quot; %{ KEY(sustain); } |
+        &quot;sweep&quot; %{ KEY(sweep); } |
+        &quot;punch&quot; %{ KEY(punch); } |
+        &quot;vibe&quot; %{ KEY(vibe); } |
+        &quot;vspeed&quot; %{ KEY(vspeed); } |
+        &quot;vdelay&quot; %{ KEY(vdelay); } |
+        &quot;volume&quot; %{ KEY(volume); };
+
+  main := |*
+    key space+ float space*   =&gt; { *((float *)key) = fval; };
+    &quot;type&quot; space+ &quot;square&quot;    =&gt; { P-&gt;type = BLOOPS_SQUARE; };
+    &quot;type&quot; space+ &quot;sawtooth&quot;  =&gt; { P-&gt;type = BLOOPS_SAWTOOTH; };
+    &quot;type&quot; space+ &quot;sine&quot;      =&gt; { P-&gt;type = BLOOPS_SINE; };
+    &quot;type&quot; space+ &quot;noise&quot;     =&gt; { P-&gt;type = BLOOPS_NOISE; };
+    space+;
+  *|;
+
+  write data nofinal;
+}%%
+
+bloopsaphone *
+bloops_sound_file(bloops *B, char *fname)
+{
+  FILE *fp;
+  struct stat stats;
+  int cs, act, len;
+  float fval;
+  void *key;
+  char *str, *p, *pe, *pf, *ts, *te, *eof = 0;
+  bloopsaphone *P;
+
+  if (stat(fname, &amp;stats) == -1)
+    return NULL;
+
+  fp = fopen(fname, &quot;rb&quot;);
+  if (!fp)
+    return NULL;
+
+  len = stats.st_size;
+  str = (char *)malloc(stats.st_size + 1);
+  if (fread(str, 1, stats.st_size, fp) != stats.st_size)
+    goto done;
+
+  p = str;
+  pe = str + len + 1;
+  p[len] = '\0';
+
+  P = bloops_square();
+  %% write init;
+  %% write exec;
+
+done:
+  fclose(fp);
+  return P;
+}
+
+char *
+bloops_sound_str(bloops *B, bloopsaphone *P)
+{
+  char *lines = (char *)malloc(4096), *str = lines;
+  bloopsaphone *sq = bloops_square();
+  if (P-&gt;type == BLOOPS_SQUARE)
+    str += sprintf(str, &quot;type square\n&quot;);
+  else if (P-&gt;type == BLOOPS_SAWTOOTH)
+    str += sprintf(str, &quot;type sawtooth\n&quot;);
+  else if (P-&gt;type == BLOOPS_SINE)
+    str += sprintf(str, &quot;type sine\n&quot;);
+  else if (P-&gt;type == BLOOPS_NOISE)
+    str += sprintf(str, &quot;type noise\n&quot;);
+
+  if (P-&gt;volume != sq-&gt;volume)
+    str += sprintf(str, &quot;volume %0.3f\n&quot;, P-&gt;volume);
+  if (P-&gt;punch != sq-&gt;punch)
+    str += sprintf(str, &quot;punch %0.3f\n&quot;, P-&gt;punch);
+  if (P-&gt;attack != sq-&gt;attack)
+    str += sprintf(str, &quot;attack %0.3f\n&quot;, P-&gt;attack);
+  if (P-&gt;sustain != sq-&gt;sustain)
+    str += sprintf(str, &quot;sustain %0.3f\n&quot;, P-&gt;sustain);
+  if (P-&gt;decay != sq-&gt;decay)
+    str += sprintf(str, &quot;decay %0.3f\n&quot;, P-&gt;decay);
+  if (P-&gt;freq != sq-&gt;freq)
+    str += sprintf(str, &quot;freq %0.3f\n&quot;, P-&gt;freq);
+  if (P-&gt;limit != sq-&gt;limit)
+    str += sprintf(str, &quot;limit %0.3f\n&quot;, P-&gt;limit);
+  if (P-&gt;slide != sq-&gt;slide)
+    str += sprintf(str, &quot;slide %0.3f\n&quot;, P-&gt;slide);
+  if (P-&gt;dslide != sq-&gt;dslide)
+    str += sprintf(str, &quot;dslide %0.3f\n&quot;, P-&gt;dslide);
+  if (P-&gt;square != sq-&gt;square)
+    str += sprintf(str, &quot;square %0.3f\n&quot;, P-&gt;square);
+  if (P-&gt;sweep != sq-&gt;sweep)
+    str += sprintf(str, &quot;sweep %0.3f\n&quot;, P-&gt;sweep);
+  if (P-&gt;vibe != sq-&gt;vibe)
+    str += sprintf(str, &quot;vibe %0.3f\n&quot;, P-&gt;vibe);
+  if (P-&gt;vspeed != sq-&gt;vspeed)
+    str += sprintf(str, &quot;vspeed %0.3f\n&quot;, P-&gt;vspeed);
+  if (P-&gt;vdelay != sq-&gt;vdelay)
+    str += sprintf(str, &quot;vdelay %0.3f\n&quot;, P-&gt;vdelay);
+  if (P-&gt;lpf != sq-&gt;lpf)
+    str += sprintf(str, &quot;lpf %0.3f\n&quot;, P-&gt;lpf);
+  if (P-&gt;lsweep != sq-&gt;lsweep)
+    str += sprintf(str, &quot;lsweep %0.3f\n&quot;, P-&gt;lsweep);
+  if (P-&gt;resonance != sq-&gt;resonance)
+    str += sprintf(str, &quot;resonance %0.3f\n&quot;, P-&gt;resonance);
+  if (P-&gt;hpf != sq-&gt;hpf)
+    str += sprintf(str, &quot;hpf %0.3f\n&quot;, P-&gt;hpf);
+  if (P-&gt;hsweep != sq-&gt;hsweep)
+    str += sprintf(str, &quot;hsweep %0.3f\n&quot;, P-&gt;hsweep);
+  if (P-&gt;arp != sq-&gt;arp)
+    str += sprintf(str, &quot;arp %0.3f\n&quot;, P-&gt;arp);
+  if (P-&gt;aspeed != sq-&gt;aspeed)
+    str += sprintf(str, &quot;aspeed %0.3f\n&quot;, P-&gt;aspeed);
+  if (P-&gt;phase != sq-&gt;phase)
+    str += sprintf(str, &quot;phase %0.3f\n&quot;, P-&gt;phase);
+  if (P-&gt;psweep != sq-&gt;psweep)
+    str += sprintf(str, &quot;psweep %0.3f\n&quot;, P-&gt;psweep);
+  if (P-&gt;repeat != sq-&gt;repeat)
+    str += sprintf(str, &quot;repeat %0.3f\n&quot;, P-&gt;repeat);
+
+  free(sq);
+  return lines;
+}</diff>
      <filename>c/notation.rl</filename>
    </modified>
    <modified>
      <diff>@@ -78,6 +78,19 @@ rb_bloops_sound_free(bloopsaphone *sound)
 }
 
 VALUE
+rb_bloops_load(VALUE self, VALUE fname)
+{
+  bloops *B;
+  bloopsaphone *P;
+  Data_Get_Struct(self, bloops, B);
+
+  StringValue(fname);
+  P = bloops_sound_file(B, RSTRING_PTR(fname));
+  if (P == NULL) return Qnil;
+  return Data_Wrap_Struct(cSound, NULL, rb_bloops_sound_free, P);
+}
+
+VALUE
 rb_bloops_sound(VALUE self, VALUE type)
 {
   bloopsaphone *P = bloops_square();
@@ -194,6 +207,7 @@ Init_bloops()
   cBloops = rb_define_class(&quot;Bloops&quot;, rb_cObject);
   rb_define_alloc_func(cBloops, rb_bloops_alloc);
   rb_define_method(cBloops, &quot;clear&quot;, rb_bloops_clear, 0);
+  rb_define_method(cBloops, &quot;load&quot;, rb_bloops_load, 1);
   rb_define_method(cBloops, &quot;play&quot;, rb_bloops_play, 0);
   rb_define_method(cBloops, &quot;sound&quot;, rb_bloops_sound, 1);
   rb_define_method(cBloops, &quot;stopped?&quot;, rb_bloops_is_stopped, 0);</diff>
      <filename>ext/ruby/rubyext.c</filename>
    </modified>
    <modified>
      <diff>@@ -5,26 +5,22 @@ b = Bloops.new
 b.tempo = 320
 
 # an instrument
-sound = b.sound Bloops::SAWTOOTH
+saw = b.sound Bloops::SAWTOOTH
 
 # assign a track to the song
-b.tune sound, &quot;c5 c6 b4 b5 d5 d6 e5 e6&quot;
+b.tune saw, &quot;c5 c6 b4 b5 d5 d6 e5 e6&quot;
 
 # make it go
 b.play
-while !b.stopped?
-  sleep 1
-end
+sleep 1 while !b.stopped?
 
 # a percussion
-sound = b.sound Bloops::NOISE
-sound.repeat = 0.6
+beat = b.sound Bloops::NOISE
+beat.repeat = 0.6
 
 # assign a track to the song
-b.tune sound, &quot;4 4 b4 4 d5 4 e5 e6&quot;
+b.tune beat, &quot;4 4 b4 4 d5 4 e5 e6&quot;
 
 # make it go
 b.play
-while !b.stopped?
-  sleep 1
-end
+sleep 1 while !b.stopped?</diff>
      <filename>ext/ruby/test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>7d3b4d1caeea602ce5d55a10c42dce7f674d6229</id>
    </parent>
  </parents>
  <author>
    <name>_why</name>
    <email>why@whytheluckystiff.net</email>
  </author>
  <url>http://github.com/localhost/bloopsaphone/commit/fbcf27fcbc522c8c076c9de5644f42245705b4ff</url>
  <id>fbcf27fcbc522c8c076c9de5644f42245705b4ff</id>
  <committed-date>2009-02-12T08:02:13-08:00</committed-date>
  <authored-date>2009-02-12T08:02:13-08:00</authored-date>
  <message> * sounds: some sample game noises... jumps, shots, darts, etc.
 * c/notation.rl: new .blu format for storing game sounds.
 * ext/ruby: added Bloop.load for loading .blu sounds.</message>
  <tree>506ef12b5b8c8ac1882a5d4f762b22f1afdb7937</tree>
  <committer>
    <name>_why</name>
    <email>why@whytheluckystiff.net</email>
  </committer>
</commit>
