Created
December 4, 2024 13:02
-
-
Save sulix/2c432dd54ffc3311f9118b3850493c7a to your computer and use it in GitHub Desktop.
CDDA Playback via Digital-Audio-Extraction on Linux w/SDL3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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