Skip to content

Instantly share code, notes, and snippets.

@sulix
Created December 4, 2024 13:02
Show Gist options
  • Save sulix/2c432dd54ffc3311f9118b3850493c7a to your computer and use it in GitHub Desktop.
Save sulix/2c432dd54ffc3311f9118b3850493c7a to your computer and use it in GitHub Desktop.
CDDA Playback via Digital-Audio-Extraction on Linux w/SDL3
// Super-hacky CD player with SDL3 and the CDROMREADAUDIO ioctl.
#include <linux/cdrom.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <SDL3/SDL.h>
#define SECTORS_AT_ONCE 4
#define MAX_SECTORS_BUFFERED 10
int main(int argc, char **argv)
{
SDL_Init(SDL_INIT_AUDIO);
SDL_AudioSpec cdda_spec = { .format = SDL_AUDIO_S16LE, .channels = 2, .freq = 44100 };
SDL_AudioStream *stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &cdda_spec, NULL, NULL);
int cdrom = open("/dev/cdrom", 0);
struct cdrom_tochdr toc;
ioctl(cdrom, CDROMREADTOCHDR, &toc);
printf("First track %d, last track %d\n", toc.cdth_trk0, toc.cdth_trk1);
for (uint8_t track = toc.cdth_trk0; track < toc.cdth_trk1; ++track)
{
struct cdrom_tocentry toce;
toce.cdte_track = track;
toce.cdte_format = CDROM_MSF;
ioctl(cdrom, CDROMREADTOCENTRY, &toce);
printf("Track %d, addr = %02d:%02d:%02d, %s\n", track, toce.cdte_addr.msf.minute, toce.cdte_addr.msf.second, toce.cdte_addr.msf.frame, (toce.cdte_ctrl & CDROM_DATA_TRACK) ? "Data" : "Audio");
}
SDL_ResumeAudioStreamDevice(stream);
struct cdrom_read_audio readaudio = {0};
readaudio.nframes = SECTORS_AT_ONCE;
readaudio.addr_format = CDROM_LBA;
while (true)
{
uint8_t buf[CD_FRAMESIZE_RAW * SECTORS_AT_ONCE];
readaudio.buf = (uint8_t*)buf;
if (ioctl(cdrom, CDROMREADAUDIO, &readaudio) < 0)
{
perror("ioctl");
break;
}
SDL_PutAudioStreamData(stream, buf, CD_FRAMESIZE_RAW * SECTORS_AT_ONCE);
readaudio.addr.lba += SECTORS_AT_ONCE;
while (SDL_GetAudioStreamQueued(stream) > CD_FRAMESIZE_RAW * MAX_SECTORS_BUFFERED)
SDL_Delay(100);
}
close (cdrom);
SDL_DestroyAudioStream(stream);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment