如何连接/展平字节数组

时间:2013-05-06 12:48:46

标签: audio clojure io clojure-java-interop

我正在创建一个生成.wav文件的函数。我已经设置了标题,但我遇到了data本身的问题。我有一个函数用于创建880Hz的正弦波(至少我认为这是它的作用,但这不是我的问题) - 问题是,如何将字节数组的集合转换为只有一个字节数组及其内容?这是我最好的尝试:

(defn lil-endian-bytes [i]
  (let [i (int i)]
  (byte-array
    (map #(.byteValue %)
         [(bit-and i 0x000000ff)
          (bit-shift-right (bit-and i 0x0000ff00) 8)
          (bit-shift-right (bit-and i 0x00ff0000) 16)
          (bit-shift-right (bit-and i 0xff000000) 24)]))))

(def leb lil-endian-bytes)

(let [wr (io/output-stream (str name ".wav") :append true)]
  (.write wr
       (byte-array (flatten (concat (map 
         (fn [sample] (leb (* 0xffff (math/sin (+ (* 2 3.14 880) sample)))))
         (range (* duration s-rate)) )))))

但它没有做我想要它做的事情:将所有字节数组连接成一个向量,然后连接到单个字节数组。这对我来说是有意义的,为什么它不能:它不能连接/压平一个字节[],因为它不是一个向量;它是一个字节[]。并且它不能将byte []转换为字节。但是我需要做些什么来实现这个目标呢?

3 个答案:

答案 0 :(得分:6)

你可能正在寻找类似的东西:

(byte-array (mapcat seq my-sequence-of-byte-arrays))

答案 1 :(得分:2)

它将如此简单:

需要在单个字节数组中组合的字节数组:

(def byte-arrays [(byte-array 10 (byte 1))
                  (byte-array 10 (byte 2))
                  (byte-array 10 (byte 3))])

联合:

(byte-array (for [ar byte-arrays
                  i ar] i))

答案 2 :(得分:1)

如果要处理大型数组,将字节数组转换为连接到序列并返回字节数组可能效率不高。这里是如何连接字节数组使java.nio.ByteBuffer做繁重的工作:

(defn concat-byte-arrays [& byte-arrays]
  (when (not-empty byte-arrays)
    (let [total-size (reduce + (map count byte-arrays))
          result     (byte-array total-size)
          bb         (java.nio.ByteBuffer/wrap result)]
      (doseq [ba byte-arrays]
        (.put bb ba))
      result)))