egedit: do not save cursor movement in undo -- this is my stupid habit, and it comple...
[iv.d.git] / chromaprint / fpcalc.d
blob35e40b140fd664db6b1a1c7a18f8cd17032879eb
1 #!/usr/bin/env rdmd
3 import iv.cmdcon;
4 import iv.chromaprint;
5 import iv.encoding;
6 import iv.vfs.io;
7 import iv.tremor;
10 enum BUF_SIZE = 4096;
11 ubyte[BUF_SIZE] buffer;
13 __gshared uint seconds = 0;
15 void main (string[] args) {
16 conRegVar!seconds("seconds", "how many seconds to process (0: whole song)");
18 concmd("exec .config.rc tan");
19 conProcessArgs!true(args);
21 if (args.length != 2) assert(0, "filename?");
22 string fname = args[1];
24 int err;
26 OggVorbis_File vf;
27 bool eof = false;
28 int currstream;
30 err = ov_fopen(VFile(fname), &vf);
31 if (err != 0) {
32 assert(0, "Error opening file '"~fname~"'");
33 } else {
34 scope(exit) ov_clear(&vf);
36 import std.string : fromStringz;
38 vorbis_info* vi = ov_info(&vf, -1);
40 long prevtime = -1;
41 long totaltime = ov_time_total(&vf);
43 stderr.writeln("Bitstream is ", vi.channels, " channel, ", vi.rate, "Hz");
44 stderr.writeln("Encoded by: ", ov_comment(&vf, -1).vendor.fromStringz.recodeToKOI8);
45 stderr.writeln("streams: ", ov_streams(&vf));
46 stderr.writeln("bitrate: ", ov_bitrate(&vf));
47 stderr.writefln("time: %d:%02d", totaltime/1000/60, totaltime/1000%60);
49 if (auto vc = ov_comment(&vf, -1)) {
50 foreach (immutable idx; 0..vc.comments) {
51 stderr.writeln(" ", vc.user_comments[idx][0..vc.comment_lengths[idx]].recodeToKOI8);
55 if (vi.channels < 1 || vi.channels > 2) {
56 stderr.writeln("ERROR: vorbis channels (", vi.channels, ")");
57 throw new Exception("vorbis error");
60 if (vi.rate < 1024 || vi.rate > 96000) {
61 stderr.writeln("ERROR: vorbis sample rate (", vi.rate, ")");
62 throw new Exception("vorbis error");
65 ChromaprintContext* cct = chromaprint_new();
66 if (cct is null) throw new Exception("can't create ChromaPrint context");
67 scope(exit) chromaprint_free(cct);
69 if (chromaprint_start(cct, vi.rate, vi.channels) == 0) throw new Exception("can't initialize ChromaPrint context");
70 //scope(exit) chromaprint_finish(cct);
72 ulong total = 0;
73 while (!eof) {
74 auto ret = ov_read(&vf, buffer.ptr, BUF_SIZE, /*0, 2, 1,*/ &currstream);
75 if (ret == 0) {
76 // EOF
77 eof = true;
78 } else if (ret < 0) {
79 // error in the stream
80 } else {
81 if (chromaprint_feed(cct, cast(const(short)*)buffer.ptr, ret/2) == 0) throw new Exception("error feeding ChromaPrint context");
82 total += ret;
83 //stderr.writeln(total/2.0/vi.channels/vi.rate*1000.0);
84 //if (total >= 1024*1024*3) { stderr.writeln("ABORT!"); break; }
85 if (seconds > 0) {
86 if (total/2.0/vi.channels/vi.rate >= seconds) { stderr.writeln("ABORT at ", total, "!"); break; }
90 stderr.writeln("TOTAL=", total);
92 chromaprint_finish(cct);
95 char *fp;
96 if (chromaprint_get_fingerprint(cct, &fp) == 0) throw new Exception("can't create ChromaPrint fingerprint");
97 scope(exit) chromaprint_dealloc(fp);
98 import core.stdc.stdio : printf;
99 printf("DURATION=%u\n", cast(uint)(totaltime/1000));
100 printf("FINGERPRINT=%s\n", fp);