summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/cRSID/host
diff options
context:
space:
mode:
authorWolfram Sang <wsa@the-dreams.de>2022-03-04 18:37:30 +0100
committerSolomon Peachy <pizza@shaftnet.org>2023-02-07 09:19:32 -0500
commite8135fea5a10dba25fefe991bf6bc36f351e2919 (patch)
treea17571dc0c1bc25a824f639be88d461245d62e89 /lib/rbcodec/codecs/cRSID/host
parent1c26f565bf0ae50495dc8d2139f76bd367728cd6 (diff)
downloadrockbox-e8135fea5a10dba25fefe991bf6bc36f351e2919.tar.gz
rockbox-e8135fea5a10dba25fefe991bf6bc36f351e2919.zip
codec: sid: add cRSID-1.0 for 21st century SID playback
Plain import of the library parts first. Adaptions to Rockbox will follow. A *lot* of kudos go to Mihaly Horvath for creating this library from his already lightweight cSID-light, mainly for Rockbox. Besides a lot of other things, he made his algorithms integer-only and significantly improved the C64 emulation, so finally RSIDs could be played as well as PSIDs. TinySID was nice for what it is, but this is a quantum leap in SID playback quality for Rockbox. Check for example: https://hvsc.csdb.dk/MUSICIANS/P/Page_Jason/Eighth.sid https://hvsc.csdb.dk/MUSICIANS/J/Jeff/Blowing.sid Change-Id: I353e12fbfd7cd8696b834616e55743e7b844a73e
Diffstat (limited to 'lib/rbcodec/codecs/cRSID/host')
-rw-r--r--lib/rbcodec/codecs/cRSID/host/audio.c62
-rw-r--r--lib/rbcodec/codecs/cRSID/host/file.c60
2 files changed, 122 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/cRSID/host/audio.c b/lib/rbcodec/codecs/cRSID/host/audio.c
new file mode 100644
index 0000000000..2e06279113
--- /dev/null
+++ b/lib/rbcodec/codecs/cRSID/host/audio.c
@@ -0,0 +1,62 @@
1
2#ifdef CRSID_PLATFORM_PC
3
4#include <SDL/SDL.h>
5
6
7void cRSID_soundCallback(void* userdata, unsigned char *buf, int len) {
8 cRSID_generateSound( (cRSID_C64instance*)userdata, buf, len );
9}
10
11
12void* cRSID_initSound(cRSID_C64instance* C64, unsigned short samplerate, unsigned short buflen) {
13 static SDL_AudioSpec soundspec;
14 if ( SDL_Init(SDL_INIT_AUDIO) < 0 ) {
15 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); return NULL;
16 }
17 soundspec.freq=samplerate; soundspec.channels=1; soundspec.format=AUDIO_S16;
18 soundspec.samples=buflen; soundspec.userdata=C64; soundspec.callback=cRSID_soundCallback;
19 if ( SDL_OpenAudio(&soundspec, NULL) < 0 ) {
20 fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError()); return NULL;
21 }
22 return (void*)&soundspec;
23}
24
25
26void cRSID_closeSound (void) {
27 SDL_PauseAudio(1); SDL_CloseAudio();
28}
29
30
31void cRSID_startSound (void) {
32 SDL_PauseAudio(0);
33}
34
35
36void cRSID_stopSound (void) {
37 SDL_PauseAudio(1);
38}
39
40
41void cRSID_generateSound(cRSID_C64instance* C64instance, unsigned char *buf, unsigned short len) {
42 static unsigned short i;
43 static int Output;
44 for(i=0;i<len;i+=2) {
45 Output=cRSID_generateSample(C64instance); //cRSID_emulateC64(C64instance);
46 //if (Output>=32767) Output=32767; else if (Output<=-32768) Output=-32768; //saturation logic on overflow
47 buf[i]=Output&0xFF; buf[i+1]=Output>>8;
48 }
49}
50
51
52#endif
53
54
55static inline signed short cRSID_generateSample (cRSID_C64instance* C64) { //call this from custom buffer-filler
56 static int Output;
57 Output=cRSID_emulateC64(C64);
58 if (C64->PSIDdigiMode) Output += cRSID_playPSIDdigi(C64);
59 if (Output>=32767) Output=32767; else if (Output<=-32768) Output=-32768; //saturation logic on overflow
60 return (signed short) Output;
61}
62
diff --git a/lib/rbcodec/codecs/cRSID/host/file.c b/lib/rbcodec/codecs/cRSID/host/file.c
new file mode 100644
index 0000000000..c87f37ebb4
--- /dev/null
+++ b/lib/rbcodec/codecs/cRSID/host/file.c
@@ -0,0 +1,60 @@
1
2
3#ifdef CRSID_PLATFORM_PC
4
5int cRSID_loadSIDfile (unsigned char* SIDfileData, char* filename, int maxlen) {
6 static signed short Data;
7 static signed int SizeCnt;
8 static FILE *SIDfile;
9
10 if ( (SIDfile=fopen(filename,"rb")) == NULL ) return CRSID_ERROR_LOAD;
11
12 SizeCnt=0;
13
14 while ( (Data=fgetc(SIDfile)) != EOF ) {
15 if (SizeCnt >= maxlen) return CRSID_ERROR_LOAD;
16 SIDfileData[SizeCnt] = Data; SizeCnt++;
17 }
18
19 fclose(SIDfile);
20 return SizeCnt;
21}
22
23#endif
24
25
26cRSID_SIDheader* cRSID_processSIDfile(cRSID_C64instance* C64, unsigned char* filedata, int filesize) {
27 int i;
28 unsigned short SIDdataOffset;
29 cRSID_SIDheader* SIDheader;
30 static const char MagicStringPSID[]="PSID";
31 //static const char MagicStringRSID[]="RSID";
32
33 C64->SIDheader = SIDheader = (cRSID_SIDheader*) filedata;
34
35 for (i=0x0000; i < 0xA000; ++i) C64->RAMbank[i]=0; //fresh start (maybe some bugged SIDs want 0 at certain RAM-locations)
36 for (i=0xC000; i < 0xD000; ++i) C64->RAMbank[i]=0;
37
38 if ( SIDheader->MagicString[0] != 'P' && SIDheader->MagicString[0] != 'R' ) return NULL;
39 for (i=1; i < (int)(sizeof(MagicStringPSID)-1); ++i) { if (SIDheader->MagicString[i] != MagicStringPSID[i]) return NULL; }
40 C64->RealSIDmode = ( SIDheader->MagicString[0] == 'R' );
41
42 if (SIDheader->LoadAddressH==0 && SIDheader->LoadAddressH==0) { //load-address taken from first 2 bytes of the C64 PRG
43 C64->LoadAddress = (filedata[SIDheader->HeaderSize+1]<<8) + (filedata[SIDheader->HeaderSize+0]);
44 SIDdataOffset = SIDheader->HeaderSize+2;
45 }
46 else { //load-adress taken from SID-header
47 C64->LoadAddress = (SIDheader->LoadAddressH<<8) + (SIDheader->LoadAddressL);
48 SIDdataOffset = SIDheader->HeaderSize;
49 }
50
51 for (i=SIDdataOffset; i<filesize; ++i) C64->RAMbank [ C64->LoadAddress + (i-SIDdataOffset) ] = filedata[i];
52
53 i = C64->LoadAddress + (filesize-SIDdataOffset);
54 C64->EndAddress = (i<0x10000) ? i : 0xFFFF;
55
56 C64->PSIDdigiMode = ( !C64->RealSIDmode && (SIDheader->ModelFormatStandard & 2) );
57
58 return C64->SIDheader;
59}
60