mirror of
https://github.com/italicsjenga/agb.git
synced 2025-01-11 17:41:33 +11:00
Merge pull request #127 from gwilymk/make-it-easier-to-configure-sound-frequencies
Make it easier to configure sound frequencies
This commit is contained in:
commit
225689b13d
|
@ -17,6 +17,9 @@ debug = true
|
||||||
[lib]
|
[lib]
|
||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
||||||
|
[features]
|
||||||
|
freq18157 = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
hound = "3.4.0"
|
hound = "3.4.0"
|
||||||
syn = "1.0.73"
|
syn = "1.0.73"
|
||||||
|
|
|
@ -12,6 +12,11 @@ use std::{
|
||||||
};
|
};
|
||||||
use syn::parse_macro_input;
|
use syn::parse_macro_input;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "freq18157"))]
|
||||||
|
const FREQUENCY: u32 = 10512;
|
||||||
|
#[cfg(feature = "freq18157")]
|
||||||
|
const FREQUENCY: u32 = 18157;
|
||||||
|
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn include_wav(input: TokenStream) -> TokenStream {
|
pub fn include_wav(input: TokenStream) -> TokenStream {
|
||||||
let input = parse_macro_input!(input as syn::LitStr);
|
let input = parse_macro_input!(input as syn::LitStr);
|
||||||
|
@ -43,8 +48,9 @@ pub fn include_wav(input: TokenStream) -> TokenStream {
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
wav_reader.spec().sample_rate,
|
wav_reader.spec().sample_rate,
|
||||||
10512,
|
FREQUENCY,
|
||||||
"agb currently only supports sample rate of 10512Hz"
|
"agb currently only supports sample rate of {}Hz",
|
||||||
|
FREQUENCY
|
||||||
);
|
);
|
||||||
|
|
||||||
let samples = samples_from_reader(wav_reader);
|
let samples = samples_from_reader(wav_reader);
|
||||||
|
|
|
@ -17,6 +17,7 @@ debug = true
|
||||||
[features]
|
[features]
|
||||||
default = ["alloc"]
|
default = ["alloc"]
|
||||||
alloc = []
|
alloc = []
|
||||||
|
freq18157 = ["agb_sound_converter/freq18157"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "1.2"
|
bitflags = "1.2"
|
||||||
|
|
|
@ -64,5 +64,5 @@ b .Initialise_mb
|
||||||
b 1b
|
b 1b
|
||||||
.pool
|
.pool
|
||||||
|
|
||||||
.include "src/sound/mixer/mixer.s"
|
|
||||||
.include "interrupt_handler.s"
|
.include "interrupt_handler.s"
|
||||||
|
.include "src/sound/mixer/mixer.s"
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
.equ SOUND_BUFFER_SIZE, 176
|
.section .iwram
|
||||||
|
.global agb_rs__buffer_size
|
||||||
|
.balign 4
|
||||||
|
agb_rs__buffer_size:
|
||||||
|
.word
|
||||||
|
|
||||||
agb_arm_func agb_rs__mixer_add
|
agb_arm_func agb_rs__mixer_add
|
||||||
@ Arguments
|
@ Arguments
|
||||||
|
@ -19,8 +23,8 @@ agb_arm_func agb_rs__mixer_add
|
||||||
modifications_fallback:
|
modifications_fallback:
|
||||||
orr r7, r7, r3, lsl #16 @ r7 now is the left channel followed by the right channel modifications.
|
orr r7, r7, r3, lsl #16 @ r7 now is the left channel followed by the right channel modifications.
|
||||||
|
|
||||||
mov r5, #0 @ current index we're reading from
|
mov r5, #0 @ current index we're reading from
|
||||||
mov r8, #SOUND_BUFFER_SIZE @ the number of steps left
|
ldr r8, agb_rs__buffer_size @ the number of steps left
|
||||||
|
|
||||||
|
|
||||||
1:
|
1:
|
||||||
|
@ -62,8 +66,8 @@ same_modification:
|
||||||
lsrs r7, r7, #1
|
lsrs r7, r7, #1
|
||||||
bne 1b
|
bne 1b
|
||||||
|
|
||||||
mov r5, #0 @ current index we're reading from
|
mov r5, #0 @ current index we're reading from
|
||||||
mov r8, #SOUND_BUFFER_SIZE @ the number of steps left
|
ldr r8, agb_rs__buffer_size @ the number of steps left
|
||||||
|
|
||||||
.macro mixer_add_loop_simple
|
.macro mixer_add_loop_simple
|
||||||
add r4, r0, r5, asr #8 @ calculate the address of the next read from the sound buffer
|
add r4, r0, r5, asr #8 @ calculate the address of the next read from the sound buffer
|
||||||
|
@ -132,7 +136,7 @@ agb_arm_func agb_rs__mixer_add_stereo
|
||||||
str r4, [r1], #4 @ store the new value, and increment the pointer
|
str r4, [r1], #4 @ store the new value, and increment the pointer
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
mov r8, #SOUND_BUFFER_SIZE
|
ldr r8, agb_rs__buffer_size
|
||||||
1:
|
1:
|
||||||
mixer_add_loop_simple_stereo
|
mixer_add_loop_simple_stereo
|
||||||
mixer_add_loop_simple_stereo
|
mixer_add_loop_simple_stereo
|
||||||
|
@ -159,8 +163,10 @@ agb_arm_func agb_rs__mixer_collapse
|
||||||
@ Arguments:
|
@ Arguments:
|
||||||
@ r0 = target buffer (i8)
|
@ r0 = target buffer (i8)
|
||||||
@ r1 = input buffer (i16) of fixnums with 4 bits of precision (read in sets of i16 in an i32)
|
@ r1 = input buffer (i16) of fixnums with 4 bits of precision (read in sets of i16 in an i32)
|
||||||
|
push {r4}
|
||||||
|
|
||||||
mov r2, #SOUND_BUFFER_SIZE @ loop counter
|
ldr r2, agb_rs__buffer_size @ loop counter
|
||||||
|
mov r4, r2
|
||||||
|
|
||||||
1:
|
1:
|
||||||
@ r12 = *r1; r1++
|
@ r12 = *r1; r1++
|
||||||
|
@ -173,11 +179,12 @@ agb_arm_func agb_rs__mixer_collapse
|
||||||
clamp_s8 r12 @ clamp the audio to 8 bit values
|
clamp_s8 r12 @ clamp the audio to 8 bit values
|
||||||
clamp_s8 r3
|
clamp_s8 r3
|
||||||
|
|
||||||
strb r3, [r0, #SOUND_BUFFER_SIZE] @ *(r0 + SOUND_BUFFER_SIZE) = r3
|
strb r3, [r0, r4] @ *(r0 + r4 = SOUND_BUFFER_SIZE) = r3
|
||||||
strb r12, [r0], #1 @ *r0 = r12; r0++
|
strb r12, [r0], #1 @ *r0 = r12; r0++
|
||||||
|
|
||||||
subs r2, r2, #1 @ r2 -= 1
|
subs r2, r2, #1 @ r2 -= 1
|
||||||
bne 1b @ loop if not 0
|
bne 1b @ loop if not 0
|
||||||
|
|
||||||
|
pop {r4}
|
||||||
bx lr
|
bx lr
|
||||||
agb_arm_end agb_rs__mixer_collapse
|
agb_arm_end agb_rs__mixer_collapse
|
||||||
|
|
|
@ -91,9 +91,26 @@ impl Mixer {
|
||||||
|
|
||||||
// I've picked one frequency that works nicely. But there are others that work nicely
|
// I've picked one frequency that works nicely. But there are others that work nicely
|
||||||
// which we may want to consider in the future: http://deku.gbadev.org/program/sound1.html
|
// which we may want to consider in the future: http://deku.gbadev.org/program/sound1.html
|
||||||
|
#[cfg(not(feature = "freq18157"))]
|
||||||
const SOUND_FREQUENCY: i32 = 10512;
|
const SOUND_FREQUENCY: i32 = 10512;
|
||||||
|
#[cfg(not(feature = "freq18157"))]
|
||||||
const SOUND_BUFFER_SIZE: usize = 176;
|
const SOUND_BUFFER_SIZE: usize = 176;
|
||||||
|
|
||||||
|
#[cfg(feature = "freq18157")]
|
||||||
|
const SOUND_FREQUENCY: i32 = 18157;
|
||||||
|
#[cfg(feature = "freq18157")]
|
||||||
|
const SOUND_BUFFER_SIZE: usize = 304;
|
||||||
|
|
||||||
|
fn set_asm_buffer_size() {
|
||||||
|
extern "C" {
|
||||||
|
static mut agb_rs__buffer_size: usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
agb_rs__buffer_size = SOUND_BUFFER_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C, align(4))]
|
#[repr(C, align(4))]
|
||||||
struct SoundBuffer([i8; SOUND_BUFFER_SIZE * 2]);
|
struct SoundBuffer([i8; SOUND_BUFFER_SIZE * 2]);
|
||||||
|
|
||||||
|
@ -106,6 +123,8 @@ struct MixerBuffer {
|
||||||
|
|
||||||
impl MixerBuffer {
|
impl MixerBuffer {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
|
set_asm_buffer_size();
|
||||||
|
|
||||||
MixerBuffer {
|
MixerBuffer {
|
||||||
buffer1: SoundBuffer([0; SOUND_BUFFER_SIZE * 2]),
|
buffer1: SoundBuffer([0; SOUND_BUFFER_SIZE * 2]),
|
||||||
buffer2: SoundBuffer([0; SOUND_BUFFER_SIZE * 2]),
|
buffer2: SoundBuffer([0; SOUND_BUFFER_SIZE * 2]),
|
||||||
|
|
Loading…
Reference in a new issue