Skip to content

feat: add Lyrics role (LRC and CDG) - #80

Draft
OnFreund wants to merge 2 commits into
Sendspin:mainfrom
OnFreund:feat/lyrics-role
Draft

feat: add Lyrics role (LRC and CDG)#80
OnFreund wants to merge 2 commits into
Sendspin:mainfrom
OnFreund:feat/lyrics-role

Conversation

@OnFreund

Copy link
Copy Markdown
Contributor

Implements #79.

Summary

  • Adds a new lyrics@v1 role for clients that display track lyrics or karaoke subtitles
  • Supports two channels (0–1) and two formats: lrc (text with embedded timestamps) and cdg (CD+G binary karaoke)
  • Lyrics are delivered as binary messages (types 12–13, assigned from the previously reserved 000011xx slot), without transport timestamps since timing is embedded in the files themselves
  • Clients can toggle channels on/off via stream/request-format without reconnecting

Details

  • client/hello: new lyrics@v1_support object with channels[] declaring format per channel (lrc | cdg | none)
  • stream/start: new lyrics object confirming active channel formats
  • stream/request-format: new lyrics object for mid-session format/channel changes
  • stream/end: lyrics added to the roles array
  • Binary message IDs 12–13 assigned to Lyrics role
  • Clearing lyrics: empty binary message (type byte only, no payload)

🤖 Generated with Claude Code

@OnFreund

Copy link
Copy Markdown
Contributor Author

Note - even though we wanted to send the lyrics inline, I looked into CDG files and they can be quite large, so I went with binary messages after all. This also keeps it consistent with artwork.

Comment thread README.md

**Supported formats:**
- `lrc` - LRC text format with embedded timestamps (UTF-8 encoded)
- `cdg` - CD+G karaoke format (binary)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lrc files are pretty ubiquitous, but I haven't heard of CD+G before.
Why should we support CD+G? I mean if it's really niche we can't depend on Sendspin implementations supporting that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have the data to back this up unfortunately, but karaoke subtitles are not niche and are well supported by both hardware and software.

@Hedda Hedda Apr 27, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lrc files are pretty ubiquitous, but I haven't heard of CD+G before.
Why should we support CD+G? I mean if it's really niche we can't depend on Sendspin implementations supporting that.

@maximmaxim345 CDG+G is not niche at all, it is an official standard for Audio-CD with Graphics (as Audio Compact Discs with digital images) that all professional Karaoke machines uses (such as used in Karaoke bars and home use), so almost all songs are available in that format.The ”G” stands for Graphics and as I understand the format is it just images for each character and as such does not need a font engine to display wierd characters for all languages. Anyway, more common nowadays are MP3+G which is just when an the redbook Audio-CD part been converted to MPG and the Graphics broken out to separate files (.cdg).

image

For player code reference I suggest check out the Kodi (formerly XBMC) codebase which supports CD+G and MP3+G

Quote from that Wikipedia article:

Along with dedicated karaoke machines, other consumer devices that play CD+G format CDs include the NEC TurboGrafx-CD (a CD-ROM peripheral for the TurboGrafx-16) and Turbo Duo, as well as the Japan-only successor the PC-FX, the Philips CD-i, the Sega CD, Sega Saturn,[5] the JVC X'Eye, the 3DO Interactive Multiplayer, the Amiga CD32 and Commodore CDTV, and the Atari Jaguar CD (an attachment for the Atari Jaguar). Some CD-ROM drives can also read this data. Pioneer's LaserActive player can also play CD+G discs, as long as either the PAC-S1/S-10 or PAC-N1/N10 game modules are installed.

Since 2003, some standalone DVD players have supported the CD+G format. Regular audio CD players will output only the audio tracks as if it was a normal music CD, unless otherwise designed to read the extra data (lyrics and images).[6]

CD+G karaoke albums are still made today by several UK and US manufacturers including Sunfly, Zoom Entertainments, SBI Karaoke and Vocal Star. Although the popularity of CD sales are dwindling the format is still widely used as MP3+G downloads.

Comment thread README.md
- `lrc` - LRC text format with embedded timestamps (UTF-8 encoded)
- `cdg` - CD+G karaoke format (binary)

**No transport timestamps:** Unlike audio or artwork, lyrics binary messages do not carry a server clock timestamp. Timing information is embedded within the lyrics data itself (e.g., `[mm:ss.xx]` tags in LRC, frame timing in CDG). The server sends lyrics at the start of each track; clients begin processing as soon as they receive them.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How will the lyrics be in sync then if it's not aligned to any timestamp?
I mean:

  • What if you pause/stop playback in the mean time, the lyrics should also stop in that case
  • Depending on the networks latency, the position in the lyrics can be different every time.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec instructs clients how to calculate track progress - can't we use that progress value to show the right lyrics? This is what I'm currently doing in my client (which is downloading lyrics independently) and it's working well.

Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md
OnFreund and others added 2 commits April 27, 2026 19:05
Closes Sendspin#79 on Sendspin/spec

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- Drop channels: single stream per role (like audio), client declares
  supported_formats in priority order, server picks one
- Use stream/end instead of empty binary message to signal no lyrics
- Add max_size_bytes to lyrics@v1_support for low-memory clients

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@Hedda

Hedda commented Aug 17, 2026

Copy link
Copy Markdown

@maximmaxim345 any chance this Lyrics role `could/will make it into the the final Sendspin v1 (1.0 version) specification?

@maximmaxim345

Copy link
Copy Markdown
Member

@maximmaxim345 any chance this Lyrics role `could/will make it into the the final Sendspin v1 (1.0 version) specification?

No, it won't make it into v1. But since Sendspin will be backwards compatible we don't need a new major Sendspin version to add a new role like lyrics.

There are still some issues with this PR I'm not fully convinced yet, those just need a bit more work to get ironed out before it's ready.

I haven't had time to look into this PR recently, but the main issues from what I remember were:

  • CD+G is IMO still a legacy format that complicates server and client implementations considerably. (looks like it's getting replaced by proprietary formats and mp4 during the past 2 decades.
  • Having both CD+G and lrc support will probably causes lrc clients to just not show anything while only the hand full of cdg compatible clients can display it, unless:
    • We force the server to convert cdg on the fly to lrc - in this case why even support cd+g in the first place?
    • We explain users why some clients work while others don't. This is a bad UX, especially if the server can't convert lrc to CD+G.
    • We force all clients to implement the CD+G spec, which is IMO not worth the complexity increase
  • It might be advantageous to use a custom messages instead of lrc if that avoids the memory issues on long tracks and improves handling on track transitions. Servers need to already replace timestamps in lrc files after all. This will also cut down the overhead when seeking since we don't need to send the whole tracks lyrics at once. < I haven't looked into this in more detail yet though.

@chrisuthe
chrisuthe marked this pull request as draft August 25, 2026 14:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants