Login
CL-RemiWav
Login

CL-RemiWav

CL-RemiWav is a library for reading and writing WAVE files. It supports (or will support) multiple bit depths and sample rates; IEEE Floating Point WAVs; and μ-law, A-law, and (some) ADPCM encodings. It also contains utilities for dithering, bit rate conversions, and ADPCM decoding/encoding.

CL-RemiWav is licensed under the GNU Affero General Public License version 3

You will need Fossil to clone this source code repository.

Wanna support me? Buy me a coffee on Ko-Fi
Buy Me a Coffee at ko-fi.com

Features

Examples

Print some information about a WAV.

(let ((wav (cl-remiwav:read-wav #P"/path/to/file.wav")))
  (format t "WAV file format: ~a-bit ~a ~a Hz ~a channel~:*~p~%"
          (cl-remiwav:wav-bit-depth wav)
          (cl-remiwav:wav-encoding wav)
          (cl-remiwav:wav-sample-rate wav)
          (cl-remiwav:wav-channels wav))
  (format t "WAV file has ~:d sample~:*~p~%"
          (truncate (length (cl-remiwav:wav-file-data wav))
                    (cl-remiwav:wav-channels wav))))

Read a WAV, then write it to another file using the streaming API.

(let ((orig (cl-remiwav:read-wav #P"/path/to/file.wav")))
  (cl-remiwav:with-output-to-wav-file
      (wav #P"/tmp/foo.wav"
           :if-exists :error ;; Don't clobber existing files
           :bit-depth (cl-remiwav:wav-bit-depth orig)
           :sample-rate (cl-remiwav:wav-sample-rate orig)
           :encoding (cl-remiwav:wav-encoding orig)
           :channels (cl-remiwav:wav-channels orig))
    (cl-remiwav:write-samples wav (cl-remiwav:wav-file-data orig))))

Generate a sine wav for 5 seconds, using a one-second buffer, and write it to a WAV using the streaming API.

(let* ((sample-rate 22050)
      (frequency 440.0d0) ;; A below middle C
      (seconds 5)
      (volume 0.5)
      (buffer (make-array sample-rate :element-type '(signed-byte 16)
                                      :initial-element 0))
      (x 0.0d0))
  (cl-remiwav:with-output-to-wav-file
      (wav #P"/path/to/new-file.wav"
           :if-exists :error ;; Don't clobber existing files
           :bit-depth 16
           :sample-rate sample-rate
           :encoding :lpcm
           :channels 1)

    ;; The buffer is only one second long, and we want 5 seconds.
    (dotimes (i 5)
      ;; Fill the buffer, which is only one second long
      (loop for idx from 0 below (length buffer) do
        (setf (aref buffer idx)
              (sdm:coerce-to-int16
                ;; Convert the float sample -> 16-bit sample
                (truncate (* 32768 (* volume (sin (/ (* pi x frequency)
                                                     sample-rate)))))))
        (incf x))
        
      ;; Write the buffer to the WAV
      (cl-remiwav:write-samples wav buffer))))

Generate a sine wav for 5 seconds, and write it to a µ-law encoded WAV using the streaming API.

(let* ((sample-rate 8000)
      (frequency 440.0d0) ;; A below middle C
      (seconds 5)
      (volume 0.5)
      (buffer (make-array (* sample-rate seconds)
                          :element-type '(signed-byte 16)
                          :initial-element 0))
      (x 0.0d0))
  (cl-remiwav:with-output-to-wav-file
      (wav #P"/path/to/new-file.wav"
           :if-exists :error ;; Don't clobber existing files
           :bit-depth 8
           :sample-rate sample-rate
           :encoding :mu-law
           :channels 1)

    ;; Fill the buffer, which is only one second long
    (loop for idx from 0 below (length buffer) do
      (setf (aref buffer idx)
            (sdm:coerce-to-int16
              ;; Convert the float sample -> 16-bit sample
              (truncate (* 32768 (* volume (sin (/ (* pi x frequency)
                                                   sample-rate)))))))
      (incf x))
        
    ;; Write the buffer to the WAV using a converter function since we have
    ;; 16-bit PCM samples.
    (cl-remiwav:write-samples wav buffer #'cl-remiwav:int16->mu-law)))

Building and Development

This has been tested with SBCL, CCL, and Clisp. Please see the Building article in the wiki for information on loading the library and running tests.

Style info

I use a slightly different style for my code.

How do I contribute?

  1. Go to https://chiselapp.com/user/MistressRemilia/repository/cl-remiwav/ and clone the Fossil repository.
  2. Create a new branch for your feature.
  3. Push locally to the new branch.
  4. Create a bundle with Fossil that contains your changes.
  5. Get in contact with me.

Contributors

Other

Test WAV files in the t/ directory are taken from http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Samples.html