3.1.2 Writing Scheme Programs with scribbu

scribbu understands both its own command-line parameters as well as those understood by the guile command. When it sees parameters applicable to guile, it will collect them and pass them on to the Scheme interpreter (when this makes sense, of course; supplying guile options while invoking a scribbu sub-command, for instance, would make no sense & results in an error). This means that scribbu can take advantage of the guile scripting options (see Guile Scripting in The Guile Reference Manual).

Continuing our example, let us capture our work so far:

#!/usr/local/bin/scribbu -e main -s
#!
(use-modules (oop goops) (scribbu))

(define (main)
    (let* ((tags (read-tagset "opium.mp3"))
           (v1   (read-id3v1-tag "opium.mp3"))
           (tag  (caar tags)))
        (slot-set! (list-ref (slot-ref tag 'frames) 2) 'dsc "sp1ff@pobox.com")
        (slot-set! v1 'genre 171)))

This Scheme program of course does nothing; it corrects the orphaned comment frame as well as the ID3v1 genre, but only in-memory. Let us write these out to disk. Writing out the ID3v1 is simpler since it’s a fixed size, so we’ll start with that:

#!/usr/local/bin/scribbu -e main -s
#!
(use-modules (oop goops) (scribbu))

(define (main)
    (let* ((tags (read-tagset "opium.mp3"))
           (v1   (read-id3v1-tag "opium.mp3"))
           (tag  (caar tags)))
        (slot-set! (list-ref (slot-ref tag 'frames) 2) 'dsc "sp1ff@pobox.com")
        (slot-set! v1 'genre 171)
        (write-id3v1-tag v1 "optimum.mp3")))

Writing an ID3v1 tag is also easier because it is appended to the file.

Function: write-id3v1-tag tag file

Write the ID3v1 tag tag to file, overwriting any (ID3v1) tag that was there previously. Nb. tag may be written as an ID3v1, ID3v1.1 and/or an ID3v1 enhanced tag, depending on the precise contents of tag.

Writing ID3v2 tagsets is more complicated, since their size can vary. write-tagset can either make a wholesale copy of the file, or attempt to emplace the new tagset at the beginning of the extant file (which is the default):

#!/usr/local/bin/scribbu -e main -s
#!
(use-modules (oop goops) (scribbu))

(define (main)
    (let* ((tags (read-tagset "opium.mp3"))
           (v1   (read-id3v1-tag "opium.mp3"))
           (tag  (caar tags)))
        (slot-set! (list-ref (slot-ref tag 'frames) 2) 'dsc "sp1ff@pobox.com")
        (slot-set! v1 'genre 171)
        (write-id3v1-tag v1 "optimum.mp3")
        (write-tagset (list (list tag 3)) "opium.mp3")))
Function: write-tagset tagset file #:copy copy #:apply-unsync apply-unsync

Write a list of <id3v2-tag> instances to file. tagset is a list of two-element lists; the first in each is the <id3v2-tag> instance to be written, the second is an integer designating the ID3v2 version to use (i.e. 2, 3 or 4)

If keyword argument copy is #t, first write the new tagset to a new file, then append file’s contents after the existing tagset (if any) to that new file, and then rename the new file over the original (making a backup copy first). Otherwise (if copy is #f, attempt to emplace the new tagset, perhaps by adjusting padding, if possible (and fallback to copying).

Keyword argument apply-unsync controls whether the unsynchronisation scheme is applied to each tag. Set this to #f (the default) to never do so, #t to always do so, and as-needed to do so only if the tag needs unsynchronisation.