Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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
Linus authored
4 CHANGELOG
... ... @@ -0,0 +1,4 @@
  1 +LuaCue 1.0.0
  2 +============
  3 +
  4 + * First release.
9 LICENSE
... ... @@ -0,0 +1,9 @@
  1 +Creative Commons CC0 License: http://creativecommons.org/publicdomain/zero/1.0/
  2 +
  3 +The person who associated a work with this document has dedicated the work
  4 +to the Commons by waiving all of his or her rights to the work worldwide
  5 +under copyright law and all related or neighboring legal rights he or she
  6 +had in the work, to the extent allowable by law.
  7 +
  8 +Works under CC0 do not require attribution. When citing the work,
  9 +you should not imply endorsement by the author.
31 README.textile
Source Rendered
... ... @@ -0,0 +1,31 @@
  1 +h1. LuaCue
  2 +
  3 +LuaCue is a cuesheet parser for Lua. It is managed by "Linus Sjögren":http://github.com/TheLinx.
  4 +The code is licensed under the CC0 license. Basically, public domain.
  5 +
  6 +h2. Dependencies
  7 +
  8 +Here's a list of stuff LuaCue needs to run:
  9 +* "CL":http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#lcl
  10 +
  11 +It should be automatically installed if you install LuaCue with LuaRocks.
  12 +
  13 +h2. How to install (with LuaRocks)
  14 +
  15 +Run the command _luarocks install http://github.com/TheLinx/LuaCue/raw/rocks/luacue-1.0.0-1.rockspec_
  16 +
  17 +h2. How to install (Manually)
  18 +
  19 +Put the folder _luahtml_ somewhere in your Lua module path.
  20 +On Linux/Mac this is usually something like _/usr/local/share/lua/5.1/_.
  21 +On Windows it's _C:\Program Files\Lua\5.1\_.
  22 +
  23 +h2. Using LuaCue in your script
  24 +
  25 +Example:
  26 +
  27 +bc. require("cue")
  28 +decodedData = cue.decode(*file name, file handle, or raw cuesheet data*)
  29 +print("Track 2 starts at "..decodedData.tracks[2].indices[1].." seconds")
  30 +
  31 +For more detailed examples, take a look at the examples.
121 cue/init.lua
... ... @@ -0,0 +1,121 @@
  1 +local cl = require("cl")
  2 +
  3 +local error,print,setmetatable,tonumber,type = error,print,setmetatable,tonumber,type
  4 +local ioOpen = io.open
  5 +local stringByte = string.byte
  6 +
  7 +module("cue")
  8 +
  9 +local function timestampToSeconds(s)
  10 + -- assumes hh:mm:ss
  11 + local h, m, s = s:match("(%d+):(%d+):(%d+)")
  12 + local h, m, s = tonumber(h)*3600, tonumber(m)*60, s
  13 + return h + m + s
  14 +end
  15 +
  16 +local o = {tracks={}}
  17 +local track = 0
  18 +
  19 +local handlers =
  20 +{
  21 + REM = function(o, k, v)
  22 + if track > 0 then
  23 + o.tracks[track][k] = v
  24 + else
  25 + o[k] = v
  26 + end
  27 + end,
  28 + TITLE = function(o, s)
  29 + if track > 0 then
  30 + o.tracks[track].title = s
  31 + else
  32 + o.title = s
  33 + end
  34 + end,
  35 + PERFORMER = function(o, s)
  36 + if track > 0 then
  37 + o.tracks[track].performer = s
  38 + else
  39 + o.performer = s
  40 + end
  41 + end,
  42 + FILE = function(o, s1, s2)
  43 + o.filename = s1
  44 + o.filetype = s2
  45 + end,
  46 + TRACK = function(o, n, s)
  47 + track = tonumber(n)
  48 + o.tracks[track] = {
  49 + type = s,
  50 + indices = {}
  51 + }
  52 + end,
  53 + ISRC = function(o, s)
  54 + o.tracks[track].isrc = s
  55 + end,
  56 + CATALOG = function(o, s)
  57 + o.catalog = s
  58 + end,
  59 + SONGWRITER = function(o, s)
  60 + if track > 0 then
  61 + o.tracks[track].songwriter = s
  62 + else
  63 + o.songwriter = s
  64 + end
  65 + end,
  66 + INDEX = function(o, n, s)
  67 + o.tracks[track].indices[n] = timestampToSeconds(s)
  68 + end
  69 +}
  70 +setmetatable(handlers, {
  71 + __index = function(t, k)
  72 + error("no handler for value "..k)
  73 + end
  74 +})
  75 +
  76 +function decode(inF)
  77 + local intype = type(inF)
  78 + if intype == "string" and not inF:find("\n") then
  79 + -- assume filename
  80 + inF = ioOpen(inF, "r")
  81 + end
  82 + local intype = type(inF)
  83 + if intype == "userdata" and inF.read then
  84 + -- assume file handle
  85 + -- UTF-8 BOM removal
  86 + local app = inF:read(3)
  87 + if app == "\239\187\191" then
  88 + app = nil
  89 + end
  90 + while true do
  91 + local n = inF:read("*l")
  92 + if not n then break end
  93 + local f,a,b = cl.unpack(n:gsub("\r", ""))
  94 + if app then
  95 + f = app..f
  96 + app = nil
  97 + end
  98 + handlers[f](o, a, b)
  99 + end
  100 + inF:close()
  101 + elseif intype == "string" then
  102 + -- assume raw cuesheet
  103 + -- UTF-8 BOM removal
  104 + if inF:match("^\239\187\191") then
  105 + inF = inF:sub(4)
  106 + end
  107 + if inF:sub(#inF) ~= "\n" then
  108 + inF = inF.."\n"
  109 + end
  110 + while true do
  111 + local n = inF:find("\n")
  112 + if not n then break end
  113 + local f,a,b = cl.unpack(inF:sub(1,n-1))
  114 + handlers[f](o, a, b)
  115 + inF = inF:sub(n+1)
  116 + end
  117 + else
  118 + error("unhandled input type", 2)
  119 + end
  120 + return o
  121 +end
54 examples/example.lua
... ... @@ -0,0 +1,54 @@
  1 +pcall(require, "printr")
  2 +package.path = "../?/init.lua;"..package.path
  3 +require("cue")
  4 +
  5 +-- from wikipedia...
  6 +sheet = [[
  7 +TITLE "Live in Berlin, 1998"
  8 +PERFORMER "Faithless"
  9 +FILE "faithless - live in berlin.mp3" MP3
  10 + TRACK 01 AUDIO
  11 + TITLE "Reverence"
  12 + PERFORMER "Faithless"
  13 + INDEX 01 00:00:00
  14 + TRACK 02 AUDIO
  15 + TITLE "She's My Baby"
  16 + PERFORMER "Faithless"
  17 + INDEX 01 06:42:00
  18 + TRACK 03 AUDIO
  19 + TITLE "Take The Long Way Home"
  20 + PERFORMER "Faithless"
  21 + INDEX 01 10:54:00
  22 + TRACK 04 AUDIO
  23 + TITLE "Insomnia"
  24 + PERFORMER "Faithless"
  25 + INDEX 01 17:04:00
  26 + TRACK 05 AUDIO
  27 + TITLE "Bring The Family Back"
  28 + PERFORMER "Faithless"
  29 + INDEX 01 25:44:00
  30 + TRACK 06 AUDIO
  31 + TITLE "Salva Mea"
  32 + PERFORMER "Faithless"
  33 + INDEX 01 30:50:00
  34 + TRACK 07 AUDIO
  35 + TITLE "Dirty Old Man"
  36 + PERFORMER "Faithless"
  37 + INDEX 01 38:24:00
  38 + TRACK 08 AUDIO
  39 + TITLE "God Is A DJ"
  40 + PERFORMER "Faithless"
  41 + INDEX 01 42:35:00]]
  42 +
  43 +decoded = cue.decode(sheet)
  44 +
  45 +if printr then
  46 + printr(decoded)
  47 +else
  48 + print("if you had a printr module, you'd see a pretty table right here")
  49 +end
  50 +
  51 +print""
  52 +
  53 +print("title of track 3: "..decoded.tracks[3].title)
  54 +print("start-index of track 7: "..decoded.tracks[7].indices[1])
53 examples/unicode.lua
... ... @@ -0,0 +1,53 @@
  1 +pcall(require, "printr")
  2 +package.path = "../?/init.lua;"..package.path
  3 +require("cue")
  4 +
  5 +-- from my music folder...
  6 +sheet = [[REM GENRE Game
  7 +REM DATE 2010
  8 +REM DISCID 49062507
  9 +REM COMMENT "ExactAudioCopy v0.99pb5"
  10 +PERFORMER "イオシス"
  11 +TITLE "東方アゲハ"
  12 +FILE "東方アゲハ.tta" WAVE
  13 + TRACK 01 AUDIO
  14 + TITLE "Letty Whiterock You!"
  15 + PERFORMER "miko"
  16 + INDEX 01 00:00:00
  17 + TRACK 02 AUDIO
  18 + TITLE "キャプテン・ムラサのケツアンカー"
  19 + PERFORMER "山本 椛"
  20 + INDEX 01 02:20:49
  21 + TRACK 03 AUDIO
  22 + TITLE "断罪ヤマザナドゥ!"
  23 + PERFORMER "岩杉 夏"
  24 + INDEX 01 05:44:01
  25 + TRACK 04 AUDIO
  26 + TITLE "てんこの恋愛下克上!エクスクラクラ☆ラメーション!"
  27 + PERFORMER "miko"
  28 + INDEX 01 09:39:39
  29 + TRACK 05 AUDIO
  30 + TITLE "水橋ジェラシックパーク"
  31 + PERFORMER "miko"
  32 + INDEX 01 12:48:26
  33 + TRACK 06 AUDIO
  34 + TITLE "ひなりんのヤクい関係"
  35 + PERFORMER "一ノ瀬 月琉"
  36 + INDEX 01 18:41:50
  37 + TRACK 07 AUDIO
  38 + TITLE "キャプテン・ARMのケツアンカー"
  39 + PERFORMER "ARM"
  40 + INDEX 01 22:53:18]]
  41 +
  42 +decoded = cue.decode(sheet)
  43 +
  44 +if printr then
  45 + printr(decoded)
  46 +else
  47 + print("if you had a printr module, you'd see a pretty table right here")
  48 +end
  49 +
  50 +print""
  51 +
  52 +print("title of track 3: "..decoded.tracks[3].title)
  53 +print("start-index of track 7: "..decoded.tracks[7].indices[1])

0 comments on commit 5a3545a

Please sign in to comment.
Something went wrong with that request. Please try again.