2013-05-06 75 views
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))))))) 

但它不會做我想做的事情:CONCAT所有的字節數組到一個載體,然後到一個單一的字節數組。它對我來說很重要,爲什麼它不能:它不能連接/壓扁一個字節[],因爲它不是一個向量;它是一個字節[]。它不能將一個字節[]轉換爲一個字節。但是,我需要做些什麼來實現這個目標?

回答

6

你可能會尋找類似:

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

好,這實際上並沒有做任何事情比我已經在做,除非有一些神奇的一個本應在發生不同'seq'功能。如果是這樣,那有什麼魔力? – tjb1982 2013-05-06 13:55:41

+1

在你的代碼中,它看起來像你在調用'(concat sequence-of-byte-arrays)'而不是'(concat byte-array-1 byte-array-2 ...)'。你可以用'(apply concat(map ...))'或者'mapcat'來解決這個問題。 – ToBeReplaced 2013-05-06 14:25:16

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)) 
+0

這真的很酷 – tjb1982 2013-05-06 16:31:26

+1

這對我來說比'(byte-array(apply concat byte-arrays))'或'(byte-array(mapcat seq byte-arrays)'''''都要少''。爲什麼要引入所有的變量名稱?正如你所說,你需要結合字節數組,所以只需'concat'它們? – ToBeReplaced 2013-05-06 19:42:56

+0

@ToBeReplaced我認爲問題是你必須以不同於concat的方式從'byte []''訪問'byte',因爲它不是集合,而是'byte []'。不過,我可能肯定是錯的。無論哪種方式,這個工作和'(byte-array(mapcat list byte-array-collection)'不適合我 – tjb1982 2013-05-06 20:07:21

0

如果您正在處理大型數組,則將字節數組轉換爲序列並返回字節數組可能會有點低效。下面是如何連接的字節數組使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)))