]> gitweb.factorcode.org Git - factor.git/blob - extra/audio/aiff/aiff.factor
Update some copyright headers to follow the current convention
[factor.git] / extra / audio / aiff / aiff.factor
1 ! Copyright (C) 2009 Joe Groff.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors alien alien.c-types alien.data audio
4 audio.chunked-file classes.struct combinators
5 combinators.short-circuit endian io io.binary
6 io.encodings.binary io.files kernel locals math sequences
7 audio.loader ;
8 IN: audio.aiff
9
10 CONSTANT: FORM-MAGIC "FORM"
11 CONSTANT: AIFF-MAGIC "AIFF"
12 CONSTANT: COMM-MAGIC "COMM"
13 CONSTANT: SSND-MAGIC "SSND"
14
15 STRUCT: aiff-chunk-header
16     { id char[4] }
17     { size char[4] } ;
18
19 STRUCT: form-chunk
20     { header aiff-chunk-header }
21     { form-type char[4] } ;
22
23 STRUCT: common-chunk
24     { header aiff-chunk-header }
25     { num-channels uchar[2] }
26     { num-sample-frames uchar[4] }
27     { sample-size uchar[2] }
28     { sample-rate uchar[10] } ;
29
30 STRUCT: sound-data-chunk
31     { header aiff-chunk-header }
32     { offset uchar[4] }
33     { block-size uchar[4] }
34     { waveform-data uchar[0] } ;
35
36 ! cheesy long-double>integer converter that assumes the long double is a positive integer
37 : sample-rate>integer ( byte[10] -- sample-rate )
38     [ 2 tail-slice be> ]
39     [ 2 head-slice be> 16383 - 63 - ] bi shift ;
40
41 : read-form-chunk ( -- byte-array/f )
42     form-chunk heap-size ensured-read* ;
43
44 : verify-aiff ( chunk -- )
45     {
46         [ FORM-MAGIC id= ]
47         [ form-chunk memory>struct form-type>> 4 memory>byte-array AIFF-MAGIC id= ]
48     } 1&&
49     [ invalid-audio-file ] unless ;
50
51 :: read-aiff-chunks ( -- comm ssnd )
52     f :> comm! f :> ssnd!
53     [ { [ comm ssnd and not ] [ read-chunk ] } 0&& dup ]
54     [ {
55         {
56             [ dup COMM-MAGIC common-chunk check-chunk ]
57             [ common-chunk memory>struct comm! ]
58         }
59         {
60             [ dup SSND-MAGIC sound-data-chunk check-chunk ]
61             [ sound-data-chunk memory>struct ssnd! ]
62         }
63         [ drop ]
64     } cond ] while drop
65     comm ssnd 2dup and [ invalid-audio-file ] unless ;
66
67 : (read-aiff) ( -- audio )
68     read-aiff-chunks
69     [
70         [ num-channels>>    2 memory>byte-array be> ]
71         [ sample-size>>     2 memory>byte-array be> ]
72         [ sample-rate>>     sample-rate>integer ] tri
73     ] [
74         [ header>> size>> 4 memory>byte-array be> 8 - dup ]
75         [ waveform-data>> >c-ptr ] bi swap memory>byte-array
76     ] bi*
77     <audio> convert-data-endian ;
78
79 : read-aiff ( filename -- audio )
80     big-endian [
81         binary [
82             read-form-chunk verify-aiff (read-aiff)
83         ] with-file-reader
84     ] with-endianness ;
85
86 "aif"  [ read-aiff ] register-audio-extension
87 "aiff" [ read-aiff ] register-audio-extension