1 /* Copyright (c) 2007-2008 CSIRO
2 Copyright (c) 2007-2009 Xiph.Org Foundation
3 Written by Jean-Marc Valin */
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 int main (string
[] args
) {
41 OpusCustomEncoder
* enc
;
42 OpusCustomDecoder
* dec;
44 opus_int32 frame_size
, channels
, rate
;
46 ubyte[OPUS_CUSTOM_MAX_PACKET
] data
;
50 if (args
.length
!= 7 && args
.length
!= 8 && args
.length
!= 3 && args
.length
!= 2) {
51 conwriteln("encode usage: opus_demo <rate> <channels> <frame size> <bytes per packet> [<complexity>] <input> <output>");
52 conwriteln("decode usage: opus_demo <input> [<output>]");
56 if (args
.length
<= 3) {
57 auto fi
= VFile(args
[1]);
59 fi
.rawReadExact(sign
[]);
60 if (sign
!= "K8CELTV0") {
61 conwriteln("invalid signature");
65 rate
= fi
.readNum
!uint;
66 channels
= fi
.readNum
!ubyte;
67 frame_size
= fi
.readNum
!ushort;
69 if (rate
< 8000 || rate
> 48000) { conwriteln("invalid sampling rate: ", rate
); return 1; }
70 if (frame_size
< 1 || frame_size
> 6000) { conwriteln("invalid frame size: ", frame_size
); return 1; }
71 if (channels
< 1 || channels
> 2) { conwriteln("invalid number of channels: ", channels
); return 1; }
73 mode
= opus_custom_mode_create(rate
, frame_size
, null);
74 if (mode
is null) { conwriteln("can't create codec"); return 1; }
75 scope(exit
) opus_custom_mode_destroy(mode
);
77 dec = opus_custom_decoder_create(mode
, channels
, &err
);
79 conwriteln("Failed to create the decoder: ", opus_strerr(err
));
82 scope(exit
) opus_custom_decoder_destroy(dec);
83 opus_custom_decoder_ctl(dec, OPUS_GET_LOOKAHEAD_REQUEST
, &skip
);
87 if (args
.length
> 2) {
88 fo
= VFile(args
[2], "w");
94 sound
.length
= 48000*2;
96 scope(exit
) alsaClose();
99 if (fi
.rawRead(bb
[0..1]).length
== 0) break;
100 if (fi
.rawRead(bb
[1..2]).length
== 0) break;
101 uint pktsize
= bb
[0]|
(bb
[1]<<8);
102 if (pktsize
< 1 || pktsize
> OPUS_CUSTOM_MAX_PACKET
) { conwriteln("invalid packet size: ", pktsize
); return 1; }
103 if (packet
.length
< pktsize
) packet
.length
= pktsize
;
104 fi
.rawReadExact(packet
[0..pktsize
]);
105 auto ret = opus_custom_decode(dec, packet
.ptr
, cast(uint)packet
.length
, sound
.ptr
, cast(uint)sound
.length
);
107 conwriteln("decode failed: ", opus_strerr(ret));
112 alsaWriteX(sound
.ptr
+skip
*channels
, (ret-skip
));
114 fo
.rawWriteExact(sound
[skip
*channels
..ret*channels
]);
116 //fwrite(out+skip*channels, sizeof(short), (ret-skip)*channels, fout);
121 rate
= args
[1].to
!opus_int32
;
122 channels
= args
[2].to
!ubyte;
123 frame_size
= args
[3].to
!ushort;
124 bytes_per_packet
= args
[4].to
!ushort;
126 if (rate
< 8000 || rate
> 48000) { conwriteln("invalid sampling rate: ", rate
); return 1; }
127 if (frame_size
< 1 || frame_size
> 6000) { conwriteln("invalid frame size: ", frame_size
); return 1; }
128 if (channels
< 1 || channels
> 2) { conwriteln("invalid number of channels: ", channels
); return 1; }
129 if (bytes_per_packet
< 1 || bytes_per_packet
> OPUS_CUSTOM_MAX_PACKET
) { conwriteln("invalid packet size: ", bytes_per_packet
); return 1; }
131 mode
= opus_custom_mode_create(rate
, frame_size
, null);
132 if (mode
is null) { conwriteln("can't create codec"); return 1; }
133 scope(exit
) opus_custom_mode_destroy(mode
);
135 auto fi
= VFile(args
[$-2]);
136 auto fo
= VFile(args
[$-1], "w");
138 enc
= opus_custom_encoder_create(mode
, channels
, &err
);
140 conwriteln("Failed to create the encoder: ", opus_strerr(err
));
143 scope(exit
) opus_custom_encoder_destroy(enc
);
145 if (args
.length
> 7) {
146 complexity
= args
[5].to
!ubyte;
147 if (complexity
> 10) { conwriteln("invalid complexity: ", complexity
); return 1; }
148 opus_custom_encoder_ctl(enc
, OPUS_SET_COMPLEXITY_REQUEST
, complexity
);
151 fo
.rawWriteExact("K8CELTV0");
152 fo
.writeNum
!uint(rate
);
153 fo
.writeNum
!ubyte(cast(ubyte)channels
);
154 fo
.writeNum
!ushort(cast(ushort)frame_size
);
157 frame
.length
= frame_size
*channels
;
160 while (pos
< frame
.length
) {
161 auto rd
= fi
.rawRead(frame
[pos
..$]);
162 if (rd
.length
== 0) break mainloop
; //FIXME
165 len
= opus_custom_encode(enc
, frame
.ptr
, frame_size
, data
.ptr
, bytes_per_packet
);
167 conwriteln("opus_custom_encode() failed: ", opus_strerr(len
));
170 if (len
> ushort.max
) assert(0, "internal error");
171 fo
.writeNum
!ushort(cast(ushort)len
);
172 fo
.rawWriteExact(data
[0..len
]);