dynne icon indicating copy to clipboard operation
dynne copied to clipboard

Accessing data for the amplitudes.

Open saolsen opened this issue 11 years ago • 1 comments

Hey,

One of the reasons I'm interested in this library is because I want to play around with some machine listening ideas. To do some of these things I think It'll be necessary to run the samples through various algorithms like an fft that are typically written to take arrays of samples and not a sampling function.

I was looking through sampled-sound.clj and see that you have a protocol that has an amplitudes function that returns the raw sample data of the sound which I think is what I'm looking for. I see it's built using a function f that takes a channel and a time so I'm wondering why this is a separate namespace and a separate protocol when the amplitude function on ISound is so similar to this function f.

Couldn't amplitudes just be a function in the sound namespace that looks something like this?

(defn amplitudes [s sample-rate]
  (let [d (duration s)
        c (channels s)]
    (for [chan (range c)]
      (hiphip.double/amake [i (* d sample-rate)]
        (sample s (double (/ i sample-rate)) chan)))))

I'm guessing there are performance reasons as to why you have a whole other namespace since that naive function above takes a really long time to run. I also probably want a way to get a lazy sequence of the samples and not load the whole thing into memory. Then again maybe I could write an fft and other processing code that works with samples and pulls the data as it needs it.

Have you thought about this much?

saolsen avatar Aug 02 '13 20:08 saolsen

The reason for the protocol is to have an abstraction that allows us to build sounds using a variety of methods. The one you point out is the constructor that builds a SampledSound via a function, but there could be lots of others. For example, you could construct an instance of SampledSound from an array, from a file, etc. etc.

The whole sampled-sound namespace is pretty half-baked right now. Its existence is motivated by my desire to make dynne ever-faster without losing the ability to compose operations the way you can right now. I have a vague thought that an array representation might be better, although I haven't gotten far enough to prove that one way or the other right now. And yes, the fact that FFT and other filtering operations are more conveniently performed on array representations is another motivation.

The other thing I've been wondering is whether it wouldn't make sense to represent sounds by writing a very thin wrapper around the stuff in javax.sound.sampled.

This whole project has been a total lark for me, really. :) I just started hacking one day and fell into the obsession-hole. Now I have something that works, and it's moved a bit towards the back burner.

I have no idea if that answers your question. Please hit me again if not.

candera avatar Aug 03 '13 15:08 candera