2

我正在制作一个生成 .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[] 转换为 byte。但是我需要做什么才能让它工作?

4

3 回答 3

7

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

(byte-array (mapcat seq my-sequence-of-byte-arrays))
于 2013-05-06T13:09:26.760 回答
4

如果您正在处理大型数组,则将要连接的字节数组转换为序列并返回字节数组可能会有点低效。以下是如何连接字节数组,使 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)))
于 2014-10-31T08:29:27.467 回答
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))
于 2013-05-06T16:29:19.567 回答