cuesheet: adding parser for cue files.
parent
6d9f5c7f00
commit
2e0eb977a2
|
@ -0,0 +1 @@
|
||||||
|
John Benediktsson
|
|
@ -0,0 +1,118 @@
|
||||||
|
USING: tools.test ;
|
||||||
|
IN: cuesheet
|
||||||
|
|
||||||
|
{
|
||||||
|
T{ cuesheet
|
||||||
|
{ files
|
||||||
|
{
|
||||||
|
T{ file
|
||||||
|
{ name "Faithless - Live in Berlin.mp3" }
|
||||||
|
{ type "MP3" }
|
||||||
|
{ tracks
|
||||||
|
{
|
||||||
|
T{ track
|
||||||
|
{ number 1 }
|
||||||
|
{ datatype "AUDIO" }
|
||||||
|
{ title "Reverence" }
|
||||||
|
{ performer "Faithless" }
|
||||||
|
{ indices { T{ index f 1 "00:00:00" } } }
|
||||||
|
}
|
||||||
|
T{ track
|
||||||
|
{ number 2 }
|
||||||
|
{ datatype "AUDIO" }
|
||||||
|
{ title "She's My Baby" }
|
||||||
|
{ performer "Faithless" }
|
||||||
|
{ indices { T{ index f 1 "06:42:00" } } }
|
||||||
|
}
|
||||||
|
T{ track
|
||||||
|
{ number 3 }
|
||||||
|
{ datatype "AUDIO" }
|
||||||
|
{ title "Take the Long Way Home" }
|
||||||
|
{ performer "Faithless" }
|
||||||
|
{ indices { T{ index f 1 "10:54:00" } } }
|
||||||
|
}
|
||||||
|
T{ track
|
||||||
|
{ number 4 }
|
||||||
|
{ datatype "AUDIO" }
|
||||||
|
{ title "Insomnia" }
|
||||||
|
{ performer "Faithless" }
|
||||||
|
{ indices { T{ index f 1 "17:04:00" } } }
|
||||||
|
}
|
||||||
|
T{ track
|
||||||
|
{ number 5 }
|
||||||
|
{ datatype "AUDIO" }
|
||||||
|
{ title "Bring the Family Back" }
|
||||||
|
{ performer "Faithless" }
|
||||||
|
{ indices { T{ index f 1 "25:44:00" } } }
|
||||||
|
}
|
||||||
|
T{ track
|
||||||
|
{ number 6 }
|
||||||
|
{ datatype "AUDIO" }
|
||||||
|
{ title "Salva Mea" }
|
||||||
|
{ performer "Faithless" }
|
||||||
|
{ indices { T{ index f 1 "30:50:00" } } }
|
||||||
|
}
|
||||||
|
T{ track
|
||||||
|
{ number 7 }
|
||||||
|
{ datatype "AUDIO" }
|
||||||
|
{ title "Dirty Old Man" }
|
||||||
|
{ performer "Faithless" }
|
||||||
|
{ indices { T{ index f 1 "38:24:00" } } }
|
||||||
|
}
|
||||||
|
T{ track
|
||||||
|
{ number 8 }
|
||||||
|
{ datatype "AUDIO" }
|
||||||
|
{ title "God Is a DJ" }
|
||||||
|
{ performer "Faithless" }
|
||||||
|
{ indices { T{ index f 1 "42:35:00" } } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{ remarks { "GENRE \"Electronica\"" "DATE \"1998\"" } }
|
||||||
|
{ performer "Faithless" }
|
||||||
|
{ title "Live in Berlin" }
|
||||||
|
}
|
||||||
|
} [
|
||||||
|
"""
|
||||||
|
REM GENRE "Electronica"
|
||||||
|
REM DATE "1998"
|
||||||
|
PERFORMER "Faithless"
|
||||||
|
TITLE "Live in Berlin"
|
||||||
|
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
|
||||||
|
""" string>cuesheet
|
||||||
|
] unit-test
|
|
@ -0,0 +1,136 @@
|
||||||
|
! Copyright (C) 2013 John Benediktsson
|
||||||
|
! See http://factorcode.org/license.txt for BSD license
|
||||||
|
|
||||||
|
USING: accessors ascii combinators io io.encodings.utf8 io.files
|
||||||
|
io.streams.string kernel math.parser sequences splitting ;
|
||||||
|
|
||||||
|
IN: cuesheet
|
||||||
|
|
||||||
|
TUPLE: cuesheet catalog cdtextfile files flags remarks performer
|
||||||
|
songwriter title ;
|
||||||
|
|
||||||
|
: <cuesheet> ( -- cuesheet )
|
||||||
|
f f f f f f f f cuesheet boa ;
|
||||||
|
|
||||||
|
TUPLE: file name type tracks ;
|
||||||
|
|
||||||
|
: <file> ( name type -- file )
|
||||||
|
f file boa ;
|
||||||
|
|
||||||
|
TUPLE: track number datatype title performer songwriter pregap
|
||||||
|
indices isrc postgap ;
|
||||||
|
|
||||||
|
: <track> ( number datatype -- track )
|
||||||
|
f f f f f f f track boa ;
|
||||||
|
|
||||||
|
TUPLE: index number duration ;
|
||||||
|
|
||||||
|
C: <index> index
|
||||||
|
|
||||||
|
ERROR: unknown-filetype filetype ;
|
||||||
|
|
||||||
|
: check-filetype ( filetype -- filetype )
|
||||||
|
dup { "BINARY" "MOTOROLA" "AIFF" "WAVE" "MP3" } member?
|
||||||
|
[ unknown-filetype ] unless ;
|
||||||
|
|
||||||
|
ERROR: unknown-flag flag ;
|
||||||
|
|
||||||
|
: check-flag ( flag -- flag )
|
||||||
|
dup { "DCP" "4CH" "PRE" "SCMS" "DATA" } member?
|
||||||
|
[ unknown-flag ] unless ;
|
||||||
|
|
||||||
|
: check-flags ( flags -- flags )
|
||||||
|
dup [ check-flag drop ] each ;
|
||||||
|
|
||||||
|
ERROR: unknown-datatype datatype ;
|
||||||
|
|
||||||
|
: check-datatype ( datatype -- datatype )
|
||||||
|
dup {
|
||||||
|
"AUDIO" "CDG" "MODE1/2048" "MODE1/2352" "MODE2/2336"
|
||||||
|
"MODE2/2352" "CDI/2336" "CDI/2352"
|
||||||
|
} member? [ unknown-datatype ] unless ;
|
||||||
|
|
||||||
|
ERROR: unknown-syntax syntax ;
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
: trim-comments ( str -- str' )
|
||||||
|
dup [ CHAR: ; = ] find drop [ head ] when* ;
|
||||||
|
|
||||||
|
: trim-quotes ( str -- str' )
|
||||||
|
[ CHAR: " = ] trim ;
|
||||||
|
|
||||||
|
: last-track ( cuesheet -- cuesheet track )
|
||||||
|
dup files>> last tracks>> last ;
|
||||||
|
|
||||||
|
: track-or-disc ( cuesheet -- cuesheet track/disc )
|
||||||
|
dup files>> [ dup ] [ last tracks>> last ] if-empty ;
|
||||||
|
|
||||||
|
: parse-file ( cuesheet str -- cuesheet )
|
||||||
|
" " split1-last [ trim-quotes ] [ check-filetype ] bi*
|
||||||
|
<file> [ suffix ] curry change-files ;
|
||||||
|
|
||||||
|
: parse-flags ( cuesheet str -- cuesheet )
|
||||||
|
check-flag [ suffix ] curry change-flags ;
|
||||||
|
|
||||||
|
: parse-index ( cuesheet str -- cuesheet )
|
||||||
|
[ last-track ] [
|
||||||
|
" " split1 [ string>number ] dip <index>
|
||||||
|
[ suffix ] curry change-indices drop
|
||||||
|
] bi* ;
|
||||||
|
|
||||||
|
: parse-isrc ( cuesheet str -- cuesheet )
|
||||||
|
[ last-track ] [ >>isrc drop ] bi* ;
|
||||||
|
|
||||||
|
: parse-performer ( cuesheet str -- cuesheet )
|
||||||
|
[ track-or-disc ] [ trim-quotes >>performer drop ] bi* ;
|
||||||
|
|
||||||
|
: parse-postgap ( cuesheet str -- cuesheet )
|
||||||
|
[ last-track ] [ >>postgap drop ] bi* ;
|
||||||
|
|
||||||
|
: parse-pregap ( cuesheet str -- cuesheet )
|
||||||
|
[ last-track ] [ >>pregap drop ] bi* ;
|
||||||
|
|
||||||
|
: parse-remarks ( cuesheet str -- cuesheet )
|
||||||
|
[ suffix ] curry change-remarks ;
|
||||||
|
|
||||||
|
: parse-songwriter ( cuesheet str -- cuesheet )
|
||||||
|
[ track-or-disc ] [ trim-quotes >>songwriter drop ] bi* ;
|
||||||
|
|
||||||
|
: parse-title ( cuesheet str -- cuesheet )
|
||||||
|
[ track-or-disc ] [ trim-quotes >>title drop ] bi* ;
|
||||||
|
|
||||||
|
: parse-track ( cuesheet str -- cuesheet )
|
||||||
|
[ dup files>> last ] [
|
||||||
|
" " split1 [ string>number ] [ check-datatype ] bi*
|
||||||
|
] bi* <track> [ suffix ] curry change-tracks drop ;
|
||||||
|
|
||||||
|
: parse-line ( cuesheet line -- cuesheet )
|
||||||
|
trim-comments [ blank? ] trim " " split1 swap {
|
||||||
|
{ "CATALOG" [ >>catalog ] }
|
||||||
|
{ "CDTEXTFILE" [ >>cdtextfile ] }
|
||||||
|
{ "FILE" [ parse-file ] }
|
||||||
|
{ "FLAGS" [ parse-flags ] }
|
||||||
|
{ "INDEX" [ parse-index ] }
|
||||||
|
{ "ISRC" [ parse-isrc ] }
|
||||||
|
{ "PERFORMER" [ parse-performer ] }
|
||||||
|
{ "POSTGAP" [ parse-postgap ] }
|
||||||
|
{ "PREGAP" [ parse-pregap ] }
|
||||||
|
{ "REM" [ parse-remarks ] }
|
||||||
|
{ "SONGWRITER" [ parse-songwriter ] }
|
||||||
|
{ "TITLE" [ parse-title ] }
|
||||||
|
{ "TRACK" [ parse-track ] }
|
||||||
|
{ "" [ drop ] }
|
||||||
|
[ unknown-syntax ]
|
||||||
|
} case ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
: read-cuesheet ( -- cuesheet )
|
||||||
|
<cuesheet> [ readln dup ] [ parse-line ] while drop ;
|
||||||
|
|
||||||
|
: file>cuesheet ( path -- cuesheet )
|
||||||
|
utf8 [ read-cuesheet ] with-file-reader ;
|
||||||
|
|
||||||
|
: string>cuesheet ( str -- cuesheet )
|
||||||
|
[ read-cuesheet ] with-string-reader ;
|
|
@ -0,0 +1 @@
|
||||||
|
Parsing cue sheet (cue files)
|
Loading…
Reference in New Issue