egra: agg mini cosmetix
[iv.d.git] / clibcelt / d / celtdemo.d
blobe8d77ed400d0edd07b93dbb15ed34ac79465f957
1 /* Copyright (c) 2007-2008 CSIRO
2 Copyright (c) 2007-2009 Xiph.Org Foundation
3 Written by Jean-Marc Valin */
4 /*
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
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.
28 import std.conv : to;
30 import iv.cmdcon;
31 import iv.vfs;
33 import iv.libcelt;
35 import xalsa;
38 int main (string[] args) {
39 int err;
40 OpusCustomMode* mode;
41 OpusCustomEncoder* enc;
42 OpusCustomDecoder* dec;
43 int len;
44 opus_int32 frame_size, channels, rate;
45 int bytes_per_packet;
46 ubyte[OPUS_CUSTOM_MAX_PACKET] data;
47 int complexity;
48 opus_int32 skip;
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>]");
53 return 1;
56 if (args.length <= 3) {
57 auto fi = VFile(args[1]);
58 char[8] sign;
59 fi.rawReadExact(sign[]);
60 if (sign != "K8CELTV0") {
61 conwriteln("invalid signature");
62 return 1;
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);
78 if (err != 0) {
79 conwriteln("Failed to create the decoder: ", opus_strerr(err));
80 return 1;
82 scope(exit) opus_custom_decoder_destroy(dec);
83 opus_custom_decoder_ctl(dec, OPUS_GET_LOOKAHEAD_REQUEST, &skip);
85 VFile fo;
86 bool doplay = true;
87 if (args.length > 2) {
88 fo = VFile(args[2], "w");
89 doplay = false;
92 ubyte[] packet;
93 short[] sound;
94 sound.length = 48000*2;
95 alsaOpen(channels);
96 scope(exit) alsaClose();
97 for (;;) {
98 ubyte[2] bb;
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);
106 if (ret < 0) {
107 conwriteln("decode failed: ", opus_strerr(ret));
108 return 1;
110 if (skip < ret) {
111 if (doplay) {
112 alsaWriteX(sound.ptr+skip*channels, (ret-skip));
113 } else {
114 fo.rawWriteExact(sound[skip*channels..ret*channels]);
116 //fwrite(out+skip*channels, sizeof(short), (ret-skip)*channels, fout);
118 skip = 0;
120 } else {
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);
139 if (err != 0) {
140 conwriteln("Failed to create the encoder: ", opus_strerr(err));
141 return 1;
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);
156 short[] frame;
157 frame.length = frame_size*channels;
158 mainloop: for (;;) {
159 uint pos = 0;
160 while (pos < frame.length) {
161 auto rd = fi.rawRead(frame[pos..$]);
162 if (rd.length == 0) break mainloop; //FIXME
163 pos += rd.length;
165 len = opus_custom_encode(enc, frame.ptr, frame_size, data.ptr, bytes_per_packet);
166 if (len <= 0) {
167 conwriteln("opus_custom_encode() failed: ", opus_strerr(len));
168 return 1;
170 if (len > ushort.max) assert(0, "internal error");
171 fo.writeNum!ushort(cast(ushort)len);
172 fo.rawWriteExact(data[0..len]);
175 return 0;