Products · D Compiler · C/C++ Compilers · DMDScript Compilers · Empire Other · Vintage PC Magazines · Vintage Magazines · Garage Sale · Audiotron |
Walter's Turtlebeach AuditronThe Turtlebeach Audiotron is an appliance that streams music from internet radio stations or a shared folder on your computer to your stereo. It's been abandoned by Turtlebeach, which is a shame as it's still the best streamer out there. I like it so much I've got three of them. What's great about the Audiotron:
The Audiotron still has a dedicated following, and I've done some things to contribute. Here's my Output.txt which is a list of radio stations in the Audiotron format. Here is the same data in a readable format. The Audiotron format is a pain to work with, so I've written a couple programs to read and write it. The first is a program written in the D programming language to convert the list of radio stations in the file to a readable and editable format: import std.stdio; import std.file; int main(string[] args) { string filename; foreach (arg; args) { filename = arg; } string input = cast(string)std.file.read(filename); dump(input); return 0; } void dump(string s) { int i = 0; int indent = 0; char get() { if (i == s.length) throw new Exception("done"); return s[i++]; } void tag(char c) { string stag; stag ~= c; while (1) { auto d = get(); if (d == '>') break; stag ~= d; } foreach (i; 0 .. indent) write(' '); writef("%s=", stag); bool any = true; while (1) { auto d = get(); if (d == '<') { d = get(); if (d == '/') { while (get() != '>') { } if (any) writeln(); break; } else { if (any) writeln(); indent++; tag(d); indent--; any = false; } } else { write(d); any = true; } } } try { while (1) { auto c = get(); if (c == '<') tag(get()); else write(c); } } catch (Exception e) { } } And a corresponding program to convert the output of the former into to be loaded back into the Audiotron: import std.stdio; import std.file; import std.string; int main(string[] args) { string infilename; string outfilename; foreach (arg; args[1..$]) { if (!infilename) infilename = arg; else if (!outfilename) outfilename = arg; } string input = cast(string)std.file.read(infilename); string output = process(input); std.file.write(outfilename, output); return 0; } string process(string s) { struct Tag { Tag* parent; Tag* sibling; Tag* child; string key; string value; } Tag* ptags; Tag* pstart; int m = 0; int stationcount = 0; auto lines = splitlines(s); foreach (line; lines) { int n; while (line.length && line[0] == ' ') { line = line[1..$]; n++; } auto t = new Tag; auto i = indexOf(line, '='); if (i == -1) continue; t.key = line[0..i]; if (t.key == "station") stationcount++; t.value = line[i + 1 .. $]; if (!ptags) { ptags = t; pstart = t; continue; } if (n == m) { ptags.sibling = t; t.parent = ptags.parent; } else if (n < m) { ptags.parent.sibling = t; t.parent = ptags.parent.parent; m = n; } else if (n > m) { ptags.child = t; t.parent = ptags; m = n; } ptags = t; } // Compute total length int totallength; Tag* tlength; void process(Tag *t) { while (t) { if (t.key == "length") { tlength = t; t.value = ""; } if (t.key == "stationcount") { t.value = std.string.format("%d", stationcount); } totallength += 1 + t.key.length + 1; totallength += t.value.length; process(t.child); totallength += 2 + t.key.length + 1; t = t.sibling; } } process(pstart); if (tlength) { string len; int i = totallength; while (1) { len = std.string.format("%d", i); if (totallength + len.length == i) break; i = totallength + len.length; } tlength.value = len; } string r; void append(Tag* t) { while (t) { r ~= "<" ~ t.key ~ ">"; r ~= t.value; append(t.child); r ~= "</" ~ t.key ~ ">"; t = t.sibling; } } append(pstart); r ~= "\r\n"; return r; } |