| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
Termtab.Parser.GP5.Internal
Description
Low-level binary decoding for the Guitar Pro 5 (.gp5) file format.
This module only knows about GP5's own binary layout — it decodes into
the GP5* types below, which mirror the file format closely (raw
duration codes, 1-based string numbers, dynamic values 1-16, etc). It
has no knowledge of Termtab.Types; Termtab.Parser.GP5 is the layer
that translates GP5* values into the domain Song.
The get* actions are meant to be run in sequence by the caller, in the
exact order fields appear in the file — there is no self-describing
structure to parse against, so getting the order or a skip length wrong
silently desynchronizes every subsequent read for the rest of the file.
Synopsis
- data GP5ScoreInfo = GP5ScoreInfo {
- gsiTitle :: Text
- gsiSubtitle :: Text
- gsiArtist :: Text
- gsiAlbum :: Text
- gsiLyricist :: Text
- gsiComposer :: Text
- data GP5MeasureHeader = GP5MeasureHeader {
- gmhTimeNum :: Int
- gmhTimeDen :: Int
- gmhKeyRoot :: Int
- gmhKeyMode :: Int
- data GP5Track = GP5Track {}
- data GP5Note = GP5Note {}
- data GP5Beat = GP5Beat {}
- data GP5Bar = GP5Bar {}
- getVersion :: Get (Int, Int)
- getScoreInfo :: Get GP5ScoreInfo
- skipLyrics :: Get ()
- skipPageSetup :: Get ()
- skipRSEMaster :: Int -> Get ()
- getTempoName :: Get Text
- getChannels :: Get [Int]
- getMeasureHeader :: Int -> (Int, Int) -> (Int, Int) -> Get GP5MeasureHeader
- getTrack :: [Int] -> Get GP5Track
- getBeat :: Get GP5Beat
- getBar :: Get GP5Bar
- getInt8' :: Get Int
- getInt32le' :: Get Int
- getU8 :: Get Int
- getByteSizeString :: Int -> Get Text
- getIntByteSizeString :: Get Text
- getIntSizeString :: Get Text
Documentation
data GP5ScoreInfo Source #
Header metadata read by getScoreInfo, decoded straight from the file
with no normalization.
Constructors
| GP5ScoreInfo | |
Fields
| |
Instances
| Show GP5ScoreInfo Source # | |
Defined in Termtab.Parser.GP5.Internal Methods showsPrec :: Int -> GP5ScoreInfo -> ShowS # show :: GP5ScoreInfo -> String # showList :: [GP5ScoreInfo] -> ShowS # | |
| Eq GP5ScoreInfo Source # | |
Defined in Termtab.Parser.GP5.Internal | |
data GP5MeasureHeader Source #
One measure header as read by getMeasureHeader. GP5 only stores a
time/key signature in the file when it changes from the previous
measure, so every field here is already resolved to its effective value
(carried forward from the previous header where the file omitted it) —
callers never need to chase "last explicit value" themselves.
Constructors
| GP5MeasureHeader | |
Fields
| |
Instances
| Show GP5MeasureHeader Source # | |
Defined in Termtab.Parser.GP5.Internal Methods showsPrec :: Int -> GP5MeasureHeader -> ShowS # show :: GP5MeasureHeader -> String # showList :: [GP5MeasureHeader] -> ShowS # | |
| Eq GP5MeasureHeader Source # | |
Defined in Termtab.Parser.GP5.Internal Methods (==) :: GP5MeasureHeader -> GP5MeasureHeader -> Bool # (/=) :: GP5MeasureHeader -> GP5MeasureHeader -> Bool # | |
One track's header as read by getTrack. gtStrings holds the open
pitch of each string (low to high count determined by string count, not
fixed at 6); gtProgram is already resolved from the channel table
passed into getTrack rather than being a raw channel index.
Constructors
| GP5Track | |
One fretted note as read by getNote. gnString is the file's
1-based string number (so gnString - 1 indexes into gtStrings);
gnDynamic is GP5's raw 1-16 dynamic level, not a MIDI velocity —
Termtab.Parser.GP5 is responsible for scaling it.
One beat as read by getBeat. gbDuration is GP5's raw signed
duration code (see decodeDuration for the mapping),
not a Duration.
One measure of one track as read by getBar — i.e. the beats for a
single (track, measure) cell of the file's bar grid.
Instances
getVersion :: Get (Int, Int) Source #
Read the file's leading 30-byte version string and parse out
(major, minor), e.g. (5, 10) for "FICHIER GUITAR PRO v5.10". Fails
(via fail) if the trailing vX.Y suffix can't be found — this is the
first read parseGP5File performs, so a failure here
means the file isn't recognizable as any version of Guitar Pro at all.
getScoreInfo :: Get GP5ScoreInfo Source #
Read the score info block: title through composer, then two more
copyright-ish strings, tab author, and instructions (all discarded),
then a variable number of "notice" strings whose count is given
in-line. Must run immediately after getVersion.
skipLyrics :: Get () Source #
Skip the lyrics block: a track number the lyrics apply to, followed by 5 lyric-line entries (each a starting-bar number plus a text blob), none of which the domain model represents.
skipPageSetup :: Get () Source #
Skip the page setup block: 36 bytes of layout numbers followed by 11 header/footer template strings. Irrelevant to playback or tab rendering.
skipRSEMaster :: Int -> Get () Source #
Skip the RSE (Realistic Sound Engine) master effect block, whose presence and size depends on the minor version: absent in GP5.0, 19 bytes in GP5.10.
getTempoName :: Get Text Source #
Read the tempo's display name (e.g. "Moderato"); the numeric BPM is read separately by the caller right after this.
getChannels :: Get [Int] Source #
Read the file's 64-slot MIDI channel table, returning each channel's
program number and discarding its volume/balance/chorus/reverb/
phaser/tremolo bytes. getTrack looks up a track's program in this
list by its 1-based channel index.
getMeasureHeader :: Int -> (Int, Int) -> (Int, Int) -> Get GP5MeasureHeader Source #
Read one measure header. idx is this measure's 0-based position
(needed only to detect the first measure's extra trailing byte); the
(prevNum, prevDen) time signature and (prevRoot, prevMode) key
signature are the previous measure's effective values, reused whenever
this header's flag bits say the signature didn't change. Caller
("Termtab.Parser.GP5.parseMeasureHeaders") is responsible for threading
each result's values into the next call.
getTrack :: [Int] -> Get GP5Track Source #
Read one track header. programs is the channel-to-program table from
getChannels, used to resolve this track's channel index into an actual
MIDI program. The file always reserves 7 string-tuning slots regardless
of instrument; only the first strCount are kept.
getBeat :: Get GP5Beat Source #
Read one beat: its rest flag and raw duration code, then optionally
skip a chord diagram, beat text, beat effects, and/or a mix table
change depending on which of its flag bits are set, then read one
GP5Note for each string flagged present in the trailing string
bitmask.
Read one bar (one measure of one track). GP5 stores two independent
voices per bar; only the first (voice0) is kept, so a second voice
layered into the same measure in the original file is silently dropped.
getByteSizeString :: Int -> Get Text Source #
Read a GP5 "byte-size string": a 1-byte length prefix followed by a
fixed-size, zero-padded field of fieldLen bytes (only the first
length bytes are meaningful). Used for fields with a fixed on-disk
width, e.g. track names.
getIntByteSizeString :: Get Text Source #
Read a GP5 "int-prefixed byte-size string": a redundant 4-byte total
length (always 1 + str_len, and discarded here), then a 1-byte
str_len, then str_len bytes of UTF-8 text. This is GP5's most common
string encoding (score metadata, track names' long form, etc).
getIntSizeString :: Get Text Source #
Read a plain length-prefixed string: a 4-byte length followed by that
many bytes of UTF-8 text (no redundant outer length, unlike
getIntByteSizeString).