Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

First release.

This is the first release of LuaCue 1.0.0. It has decoding
functionality, ready to be used and abused. Thanks to the
"Wikipedia article on cuesheets":[1] as provided an
easy-to-understand documentation of the cuesheet format.
Also, thanks to "lhf":[2] and "jA_cOp":[3] for helping me out in
the Lua IRC channel.
List of features:

  * Cuesheet decoding.
  * Basic UTF-8 compliance (it "will work" with UTF-8 input files)

[1]:http://en.wikipedia.org/wiki/Cue_sheet_(computing)
[2]:http://www.tecgraf.puc-rio.br/~lhf/
[3]:http://github.com/JakobOvrum
  • Loading branch information...
commit 5a3545a21b53d0f05f6636935a84704294220f93 0 parents
@TheLinx authored
4 CHANGELOG
@@ -0,0 +1,4 @@
+LuaCue 1.0.0
+============
+
+ * First release.
9 LICENSE
@@ -0,0 +1,9 @@
+Creative Commons CC0 License: http://creativecommons.org/publicdomain/zero/1.0/
+
+The person who associated a work with this document has dedicated the work
+to the Commons by waiving all of his or her rights to the work worldwide
+under copyright law and all related or neighboring legal rights he or she
+had in the work, to the extent allowable by law.
+
+Works under CC0 do not require attribution. When citing the work,
+you should not imply endorsement by the author.
31 README.textile
@@ -0,0 +1,31 @@
+h1. LuaCue
+
+LuaCue is a cuesheet parser for Lua. It is managed by "Linus Sjögren":http://github.com/TheLinx.
+The code is licensed under the CC0 license. Basically, public domain.
+
+h2. Dependencies
+
+Here's a list of stuff LuaCue needs to run:
+* "CL":http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#lcl
+
+It should be automatically installed if you install LuaCue with LuaRocks.
+
+h2. How to install (with LuaRocks)
+
+Run the command _luarocks install http://github.com/TheLinx/LuaCue/raw/rocks/luacue-1.0.0-1.rockspec_
+
+h2. How to install (Manually)
+
+Put the folder _luahtml_ somewhere in your Lua module path.
+On Linux/Mac this is usually something like _/usr/local/share/lua/5.1/_.
+On Windows it's _C:\Program Files\Lua\5.1\_.
+
+h2. Using LuaCue in your script
+
+Example:
+
+bc. require("cue")
+decodedData = cue.decode(*file name, file handle, or raw cuesheet data*)
+print("Track 2 starts at "..decodedData.tracks[2].indices[1].." seconds")
+
+For more detailed examples, take a look at the examples.
121 cue/init.lua
@@ -0,0 +1,121 @@
+local cl = require("cl")
+
+local error,print,setmetatable,tonumber,type = error,print,setmetatable,tonumber,type
+local ioOpen = io.open
+local stringByte = string.byte
+
+module("cue")
+
+local function timestampToSeconds(s)
+ -- assumes hh:mm:ss
+ local h, m, s = s:match("(%d+):(%d+):(%d+)")
+ local h, m, s = tonumber(h)*3600, tonumber(m)*60, s
+ return h + m + s
+end
+
+local o = {tracks={}}
+local track = 0
+
+local handlers =
+{
+ REM = function(o, k, v)
+ if track > 0 then
+ o.tracks[track][k] = v
+ else
+ o[k] = v
+ end
+ end,
+ TITLE = function(o, s)
+ if track > 0 then
+ o.tracks[track].title = s
+ else
+ o.title = s
+ end
+ end,
+ PERFORMER = function(o, s)
+ if track > 0 then
+ o.tracks[track].performer = s
+ else
+ o.performer = s
+ end
+ end,
+ FILE = function(o, s1, s2)
+ o.filename = s1
+ o.filetype = s2
+ end,
+ TRACK = function(o, n, s)
+ track = tonumber(n)
+ o.tracks[track] = {
+ type = s,
+ indices = {}
+ }
+ end,
+ ISRC = function(o, s)
+ o.tracks[track].isrc = s
+ end,
+ CATALOG = function(o, s)
+ o.catalog = s
+ end,
+ SONGWRITER = function(o, s)
+ if track > 0 then
+ o.tracks[track].songwriter = s
+ else
+ o.songwriter = s
+ end
+ end,
+ INDEX = function(o, n, s)
+ o.tracks[track].indices[n] = timestampToSeconds(s)
+ end
+}
+setmetatable(handlers, {
+ __index = function(t, k)
+ error("no handler for value "..k)
+ end
+})
+
+function decode(inF)
+ local intype = type(inF)
+ if intype == "string" and not inF:find("\n") then
+ -- assume filename
+ inF = ioOpen(inF, "r")
+ end
+ local intype = type(inF)
+ if intype == "userdata" and inF.read then
+ -- assume file handle
+ -- UTF-8 BOM removal
+ local app = inF:read(3)
+ if app == "\239\187\191" then
+ app = nil
+ end
+ while true do
+ local n = inF:read("*l")
+ if not n then break end
+ local f,a,b = cl.unpack(n:gsub("\r", ""))
+ if app then
+ f = app..f
+ app = nil
+ end
+ handlers[f](o, a, b)
+ end
+ inF:close()
+ elseif intype == "string" then
+ -- assume raw cuesheet
+ -- UTF-8 BOM removal
+ if inF:match("^\239\187\191") then
+ inF = inF:sub(4)
+ end
+ if inF:sub(#inF) ~= "\n" then
+ inF = inF.."\n"
+ end
+ while true do
+ local n = inF:find("\n")
+ if not n then break end
+ local f,a,b = cl.unpack(inF:sub(1,n-1))
+ handlers[f](o, a, b)
+ inF = inF:sub(n+1)
+ end
+ else
+ error("unhandled input type", 2)
+ end
+ return o
+end
54 examples/example.lua
@@ -0,0 +1,54 @@
+pcall(require, "printr")
+package.path = "../?/init.lua;"..package.path
+require("cue")
+
+-- from wikipedia...
+sheet = [[
+TITLE "Live in Berlin, 1998"
+PERFORMER "Faithless"
+FILE "faithless - live in berlin.mp3" MP3
+ TRACK 01 AUDIO
+ TITLE "Reverence"
+ PERFORMER "Faithless"
+ INDEX 01 00:00:00
+ TRACK 02 AUDIO
+ TITLE "She's My Baby"
+ PERFORMER "Faithless"
+ INDEX 01 06:42:00
+ TRACK 03 AUDIO
+ TITLE "Take The Long Way Home"
+ PERFORMER "Faithless"
+ INDEX 01 10:54:00
+ TRACK 04 AUDIO
+ TITLE "Insomnia"
+ PERFORMER "Faithless"
+ INDEX 01 17:04:00
+ TRACK 05 AUDIO
+ TITLE "Bring The Family Back"
+ PERFORMER "Faithless"
+ INDEX 01 25:44:00
+ TRACK 06 AUDIO
+ TITLE "Salva Mea"
+ PERFORMER "Faithless"
+ INDEX 01 30:50:00
+ TRACK 07 AUDIO
+ TITLE "Dirty Old Man"
+ PERFORMER "Faithless"
+ INDEX 01 38:24:00
+ TRACK 08 AUDIO
+ TITLE "God Is A DJ"
+ PERFORMER "Faithless"
+ INDEX 01 42:35:00]]
+
+decoded = cue.decode(sheet)
+
+if printr then
+ printr(decoded)
+else
+ print("if you had a printr module, you'd see a pretty table right here")
+end
+
+print""
+
+print("title of track 3: "..decoded.tracks[3].title)
+print("start-index of track 7: "..decoded.tracks[7].indices[1])
53 examples/unicode.lua
@@ -0,0 +1,53 @@
+pcall(require, "printr")
+package.path = "../?/init.lua;"..package.path
+require("cue")
+
+-- from my music folder...
+sheet = [[REM GENRE Game
+REM DATE 2010
+REM DISCID 49062507
+REM COMMENT "ExactAudioCopy v0.99pb5"
+PERFORMER "イオシス"
+TITLE "東方アゲハ"
+FILE "東方アゲハ.tta" WAVE
+ TRACK 01 AUDIO
+ TITLE "Letty Whiterock You!"
+ PERFORMER "miko"
+ INDEX 01 00:00:00
+ TRACK 02 AUDIO
+ TITLE "キャプテン・ムラサのケツアンカー"
+ PERFORMER "山本 椛"
+ INDEX 01 02:20:49
+ TRACK 03 AUDIO
+ TITLE "断罪ヤマザナドゥ!"
+ PERFORMER "岩杉 夏"
+ INDEX 01 05:44:01
+ TRACK 04 AUDIO
+ TITLE "てんこの恋愛下克上!エクスクラクラ☆ラメーション!"
+ PERFORMER "miko"
+ INDEX 01 09:39:39
+ TRACK 05 AUDIO
+ TITLE "水橋ジェラシックパーク"
+ PERFORMER "miko"
+ INDEX 01 12:48:26
+ TRACK 06 AUDIO
+ TITLE "ひなりんのヤクい関係"
+ PERFORMER "一ノ瀬 月琉"
+ INDEX 01 18:41:50
+ TRACK 07 AUDIO
+ TITLE "キャプテン・ARMのケツアンカー"
+ PERFORMER "ARM"
+ INDEX 01 22:53:18]]
+
+decoded = cue.decode(sheet)
+
+if printr then
+ printr(decoded)
+else
+ print("if you had a printr module, you'd see a pretty table right here")
+end
+
+print""
+
+print("title of track 3: "..decoded.tracks[3].title)
+print("start-index of track 7: "..decoded.tracks[7].indices[1])
Please sign in to comment.
Something went wrong with that request. Please try again.