termtab-0.1.0.0: TUI guitar tablature and score editor
Safe HaskellNone
LanguageGHC2021

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

Documentation

data GP5ScoreInfo Source #

Header metadata read by getScoreInfo, decoded straight from the file with no normalization.

Instances

Instances details
Show GP5ScoreInfo Source # 
Instance details

Defined in Termtab.Parser.GP5.Internal

Eq GP5ScoreInfo Source # 
Instance details

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.

data GP5Track Source #

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 

Instances

Instances details
Show GP5Track Source # 
Instance details

Defined in Termtab.Parser.GP5.Internal

Eq GP5Track Source # 
Instance details

Defined in Termtab.Parser.GP5.Internal

data GP5Note Source #

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.

Constructors

GP5Note 

Fields

Instances

Instances details
Show GP5Note Source # 
Instance details

Defined in Termtab.Parser.GP5.Internal

Eq GP5Note Source # 
Instance details

Defined in Termtab.Parser.GP5.Internal

Methods

(==) :: GP5Note -> GP5Note -> Bool #

(/=) :: GP5Note -> GP5Note -> Bool #

data GP5Beat Source #

One beat as read by getBeat. gbDuration is GP5's raw signed duration code (see decodeDuration for the mapping), not a Duration.

Constructors

GP5Beat 

Fields

Instances

Instances details
Show GP5Beat Source # 
Instance details

Defined in Termtab.Parser.GP5.Internal

Eq GP5Beat Source # 
Instance details

Defined in Termtab.Parser.GP5.Internal

Methods

(==) :: GP5Beat -> GP5Beat -> Bool #

(/=) :: GP5Beat -> GP5Beat -> Bool #

data GP5Bar Source #

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.

Constructors

GP5Bar 

Fields

Instances

Instances details
Show GP5Bar Source # 
Instance details

Defined in Termtab.Parser.GP5.Internal

Eq GP5Bar Source # 
Instance details

Defined in Termtab.Parser.GP5.Internal

Methods

(==) :: GP5Bar -> GP5Bar -> Bool #

(/=) :: GP5Bar -> GP5Bar -> Bool #

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.

getBar :: Get GP5Bar Source #

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.

getInt8' :: Get Int Source #

Read one byte as a signed Int (-128 to 127); plain getInt8 with the sign already applied for callers working in Int.

getInt32le' :: Get Int Source #

Read a little-endian 32-bit signed integer as Int.

getU8 :: Get Int Source #

Read one byte as an unsigned Int (0-255).

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).