Some changes
This commit is contained in:
79
peripherals/audio.c
Normal file
79
peripherals/audio.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
// Created by bruno on 16.2.2025.
|
||||
*/
|
||||
|
||||
#include "audio.h"
|
||||
|
||||
int pcm_buffer_empty(PcmVoice *pcm) {
|
||||
return pcm->head == pcm->tail;
|
||||
}
|
||||
|
||||
int pcm_buffer_full(PcmVoice *pcm) {
|
||||
return ((pcm->tail + 1) % PCM_BUFFER_SIZE) == pcm->head;
|
||||
}
|
||||
|
||||
void pcm_buffer_push(PcmVoice *pcm, uint16_t sample) {
|
||||
if (!pcm_buffer_full(pcm)) {
|
||||
pcm->buffer[pcm->tail] = sample;
|
||||
pcm->tail = (pcm->tail + 1) % PCM_BUFFER_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t pcm_buffer_pop(PcmVoice *pcm) {
|
||||
if (!pcm_buffer_empty(pcm)) {
|
||||
uint16_t sample = pcm->buffer[pcm->head];
|
||||
pcm->head = (pcm->head + 1) % PCM_BUFFER_SIZE;
|
||||
return sample;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void audio_callback(void *userdata, Uint8 *stream, int len) {
|
||||
AudioData *audio = (AudioData *) userdata;
|
||||
int samples = len / sizeof(float);
|
||||
|
||||
for (int i = 0; i < samples; i++) {
|
||||
float mix = 0.0f;
|
||||
int activeVoices = 0;
|
||||
|
||||
for (int v = 0; v < NUM_SYNTH_VOICES; v++) {
|
||||
SynthVoice *voice = &audio->synthVoices[v];
|
||||
if (voice->volume == 0 || voice->frequency == 0) continue;
|
||||
|
||||
float sample = 0.0f;
|
||||
float t = (float) voice->phase / 255.0f * 2.0f - 1.0f;
|
||||
|
||||
switch (voice->waveform) {
|
||||
default:
|
||||
case WAVE_SINE:
|
||||
sample = sinf(voice->phase * 2.0f * M_PI / 256.0f);
|
||||
break;
|
||||
case WAVE_SQUARE:
|
||||
sample = (t >= 0.0f) ? 1.0f : -1.0f;
|
||||
break;
|
||||
case WAVE_SAWTOOTH:
|
||||
sample = t;
|
||||
break;
|
||||
case WAVE_TRIANGLE:
|
||||
sample = (t < 0) ? -t : t;
|
||||
break;
|
||||
case WAVE_NOISE:
|
||||
sample = ((float) rand() / RAND_MAX) * 2.0f - 1.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
voice->phase += (uint8_t) ((voice->frequency * 256) / SAMPLE_RATE);
|
||||
mix += sample * (voice->volume / 255.0f);
|
||||
activeVoices++;
|
||||
}
|
||||
|
||||
PcmVoice *pcm = &audio->pcmVoice;
|
||||
if (pcm->volume > 0 && !pcm_buffer_empty(pcm)) {
|
||||
float pcmSample = pcm_buffer_pop(pcm) / 65535.0f;
|
||||
mix += pcmSample * (pcm->volume / 255.0f);
|
||||
activeVoices++;
|
||||
}
|
||||
|
||||
((float *) stream)[i] = (activeVoices > 0) ? mix / activeVoices : 0.0f;
|
||||
}
|
||||
}
|
55
peripherals/audio.h
Normal file
55
peripherals/audio.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
// Created by bruno on 16.2.2025.
|
||||
*/
|
||||
|
||||
#ifndef RISCB_AUDIO_H
|
||||
#define RISCB_AUDIO_H
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define SAMPLE_RATE 44100
|
||||
#define NUM_SYNTH_VOICES 3
|
||||
#define PCM_BUFFER_SIZE 4096
|
||||
|
||||
typedef enum {
|
||||
WAVE_SINE,
|
||||
WAVE_SQUARE,
|
||||
WAVE_SAWTOOTH,
|
||||
WAVE_TRIANGLE,
|
||||
WAVE_NOISE
|
||||
} Waveform;
|
||||
|
||||
typedef struct {
|
||||
uint8_t volume;
|
||||
uint16_t frequency;
|
||||
uint8_t phase;
|
||||
Waveform waveform;
|
||||
} SynthVoice;
|
||||
|
||||
typedef struct {
|
||||
uint8_t volume;
|
||||
uint8_t upsample_factor;
|
||||
uint8_t upsample_count;
|
||||
uint16_t buffer[PCM_BUFFER_SIZE];
|
||||
size_t head, tail;
|
||||
} PcmVoice;
|
||||
|
||||
typedef struct {
|
||||
SynthVoice synthVoices[NUM_SYNTH_VOICES];
|
||||
PcmVoice pcmVoice;
|
||||
} AudioData;
|
||||
|
||||
int pcm_buffer_empty(PcmVoice *pcm);
|
||||
|
||||
int pcm_buffer_full(PcmVoice *pcm);
|
||||
|
||||
void pcm_buffer_push(PcmVoice *pcm, uint16_t sample);
|
||||
|
||||
uint16_t pcm_buffer_pop(PcmVoice *pcm);
|
||||
|
||||
void audio_callback(void *userdata, Uint8 *stream, int len);
|
||||
|
||||
#endif //RISCB_AUDIO_H
|
7
peripherals/peripheraldata.c
Normal file
7
peripherals/peripheraldata.c
Normal file
@@ -0,0 +1,7 @@
|
||||
//
|
||||
// Created by bruno on 16.2.2025.
|
||||
//
|
||||
|
||||
#include "peripheraldata.h"
|
||||
|
||||
AudioData audioData;
|
11
peripherals/peripheraldata.h
Normal file
11
peripherals/peripheraldata.h
Normal file
@@ -0,0 +1,11 @@
|
||||
//
|
||||
// Created by bruno on 16.2.2025.
|
||||
//
|
||||
|
||||
#ifndef RISCB_PERIPHERALDATA_H
|
||||
#define RISCB_PERIPHERALDATA_H
|
||||
|
||||
#include "audio.h"
|
||||
|
||||
extern AudioData audioData;
|
||||
#endif //RISCB_PERIPHERALDATA_H
|
Reference in New Issue
Block a user