model.scm 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. (library (model)
  2. (export ;; Constants
  3. BITS-PER-BYTE
  4. EXTRA-FORMAT-BYTES
  5. FORMAT-SIZE-NO-EXTRA-BYTES
  6. COMPRESSION-CODE-BYTES
  7. NUM-CHANNELS-BYTES
  8. SAMPLE-RATE-BYTES
  9. AVG-BYTE-RATE-BYTES
  10. BLOCK-ALIGN-BYTES
  11. SIGNIFICANT-BITS-PER-SAMPLE-BYTES
  12. ;; construct-header-chunk
  13. make-riff-wave
  14. riff-wave?
  15. riff-wave-header-chunk
  16. riff-wave-format-chunk
  17. riff-wave-data-chunk
  18. make-header-chunk
  19. header-chunk?
  20. header-chunk-id
  21. header-chunk-size
  22. header-chunk-riff-type
  23. ;; construct-format-chunk
  24. make-format-chunk
  25. format-chunk?
  26. format-chunk-id
  27. format-chunk-size
  28. format-chunk-compression-code
  29. format-chunk-num-channels
  30. format-chunk-sample-rate
  31. format-chunk-avg-byte-rate
  32. format-chunk-block-align
  33. format-chunk-significant-bits-per-sample
  34. ;; construct-data-chunk
  35. make-data-chunk
  36. data-chunk?
  37. data-chunk-id
  38. data-chunk-size
  39. data-chunk-samples
  40. calculate-format-chunk-size
  41. calculate-data-chunk-size
  42. calculate-header-chunk-size)
  43. (import (except (rnrs base) let-values)
  44. (only (guile)
  45. lambda* λ)
  46. ;; (ice-9 exceptions)
  47. ;; (ice-9 binary-ports)
  48. ;; (rnrs bytevectors)
  49. ;; (srfi srfi-43)
  50. ;; structs
  51. (srfi srfi-9)
  52. ;; functional structs
  53. (srfi srfi-9 gnu)
  54. (bytevector-utils))
  55. (define BITS-PER-BYTE 8)
  56. (define EXTRA-FORMAT-BYTES 0)
  57. (define FORMAT-SIZE-NO-EXTRA-BYTES 16)
  58. (define COMPRESSION-CODE-BYTES 2)
  59. (define NUM-CHANNELS-BYTES 2)
  60. (define SAMPLE-RATE-BYTES 4)
  61. (define AVG-BYTE-RATE-BYTES 4)
  62. (define BLOCK-ALIGN-BYTES 2)
  63. (define SIGNIFICANT-BITS-PER-SAMPLE-BYTES 2)
  64. (define calculate-data-chunk-size
  65. (λ (num-samples bit-depth num-channels)
  66. ;; in bytes
  67. (/
  68. ;; per channel a sample of bit-depth bits
  69. (* num-samples bit-depth num-channels)
  70. ;; 8 bits in a byte
  71. 8)))
  72. (define calculate-format-chunk-size
  73. (λ (extra-format-bytes-count)
  74. (let ([size-without-extra-format-bytes 16])
  75. (+ size-without-extra-format-bytes
  76. extra-format-bytes-count))))
  77. (define calculate-header-chunk-size
  78. (λ (format-chunk-size data-chunk-size)
  79. "This is the size of the whole file, minus the 8 bytes spent
  80. on expressing the id and the size."
  81. (+
  82. ;; id is in 4 bytes, 4 ascii characters
  83. 4
  84. ;; id and size of the format chunk + format chunk size
  85. (+ 8 format-chunk-size)
  86. ;; id and size of the data chunk + data chunk size
  87. (+ 8 data-chunk-size))))
  88. (define-immutable-record-type <riff-wave>
  89. (make-riff-wave header-chunk
  90. format-chunk
  91. data-chunk)
  92. riff-wave?
  93. (header-chunk riff-wave-header-chunk)
  94. (format-chunk riff-wave-format-chunk)
  95. (data-chunk riff-wave-data-chunk))
  96. (define-immutable-record-type <header-chunk>
  97. (construct-header-chunk id size riff-type)
  98. header-chunk?
  99. (id header-chunk-id)
  100. (size header-chunk-size)
  101. (riff-type header-chunk-riff-type))
  102. (define make-header-chunk
  103. (λ (size)
  104. (construct-header-chunk "RIFF"
  105. size
  106. "WAVE")))
  107. (define-immutable-record-type <format-chunk>
  108. (construct-format-chunk id
  109. size
  110. compression-code
  111. num-channels
  112. sample-rate
  113. avg-byte-rate
  114. block-align
  115. significant-bits-per-sample)
  116. format-chunk?
  117. (id format-chunk-id)
  118. (size format-chunk-size)
  119. (compression-code format-chunk-compression-code)
  120. (num-channels format-chunk-num-channels)
  121. (sample-rate format-chunk-sample-rate)
  122. (avg-byte-rate format-chunk-avg-byte-rate)
  123. (block-align format-chunk-block-align)
  124. (significant-bits-per-sample format-chunk-significant-bits-per-sample))
  125. (define make-format-chunk
  126. (λ (compression-code
  127. num-channels
  128. sample-rate
  129. bit-depth)
  130. (construct-format-chunk "fmt "
  131. (+ FORMAT-SIZE-NO-EXTRA-BYTES
  132. EXTRA-FORMAT-BYTES)
  133. compression-code
  134. num-channels
  135. sample-rate
  136. ;; Each sample takes bit-depth
  137. ;; bits for each channel ->
  138. ;; bit-depth * number of
  139. ;; channels.
  140. (/ (* sample-rate bit-depth)
  141. BITS-PER-BYTE)
  142. (* num-channels
  143. (/ bit-depth BITS-PER-BYTE))
  144. bit-depth)))
  145. (define-record-type <data-chunk>
  146. (construct-data-chunk id size samples)
  147. data-chunk?
  148. (id data-chunk-id)
  149. (size data-chunk-size)
  150. (samples data-chunk-samples))
  151. (define make-data-chunk
  152. (λ (samples bit-depth num-channels)
  153. (construct-data-chunk "data"
  154. (calculate-data-chunk-size (vector-length samples)
  155. bit-depth
  156. num-channels)
  157. samples))))