Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Libretro
retro8
Commits
e9fd1973
Commit
e9fd1973
authored
Dec 16, 2019
by
Jack
Browse files
working on sound rendering
parent
3d5b532d
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/views/game_view.cpp
View file @
e9fd1973
...
...
@@ -113,8 +113,8 @@ void GameView::render()
if
(
machine
.
code
().
hasInit
())
machine
.
code
().
init
();
/
*
machine.sound().init();
machine.sound().resume();
*/
/
/
machine.sound().init();
//
machine.sound().resume();
/*for (int i = 0; i < 32; ++i)
machine.circ(64, 64, i+1, (r8::color_t)(i % 15 + 1));*/
...
...
src/vm/sound.cpp
View file @
e9fd1973
...
...
@@ -156,16 +156,16 @@ DSP dsp(44100);
constexpr
float
PULSE_WAVE_DEFAULT_DUTY
=
1
/
3.0
f
;
constexpr
float
ORGAN_DEFAULT_COEFFICIENT
=
0.5
f
;
enum
Note
{
C
,
CS
,
D
,
DS
,
E
,
F
,
FS
,
G
,
GS
,
A
,
AS
,
B
};
const
std
::
array
<
float
,
12
>
NoteTable
=
{
130.81
f
,
138.59
f
,
146.83
f
,
155.56
f
,
164.81
f
,
174.61
f
,
185.00
f
,
196.00
,
207.65
,
220.0
,
233.08
,
246.94
};
size_t
position
=
0
;
int16_t
*
rendered
=
nullptr
;
void
audio_callback
(
void
*
data
,
uint8_t
*
cbuffer
,
int
length
)
{
APU
*
apu
=
static_cast
<
APU
*>
(
data
);
int16_t
*
buffer
=
reinterpret_cast
<
int16_t
*>
(
cbuffer
);
apu
->
renderSounds
(
buffer
,
length
/
sizeof
(
int16_t
));
return
;
if
(
!
rendered
)
{
rendered
=
new
int16_t
[
44100
*
3
];
...
...
@@ -175,7 +175,7 @@ void audio_callback(void* data, uint8_t* cbuffer, int length)
}
//
APU* apu = static_cast<APU*>(data);
//
//int16_t* buffer = reinterpret_cast<int16_t*>(cbuffer);
if
(
position
<
44100
*
3
)
...
...
@@ -214,12 +214,69 @@ void APU::init()
}
}
Sound
ssound
;
SoundState
sstate
;
void
APU
::
resume
()
{
ssound
.
speed
=
32
;
ssound
.
samples
[
0
].
setPitch
(
Note
::
pitch
(
Tone
::
E
,
2
));
ssound
.
samples
[
1
].
setPitch
(
Note
::
pitch
(
Tone
::
E
,
2
));
ssound
.
samples
[
2
].
setPitch
(
Note
::
pitch
(
Tone
::
F
,
2
));
ssound
.
samples
[
3
].
setPitch
(
Note
::
pitch
(
Tone
::
G
,
2
));
ssound
.
samples
[
4
].
setPitch
(
Note
::
pitch
(
Tone
::
G
,
2
));
ssound
.
samples
[
5
].
setPitch
(
Note
::
pitch
(
Tone
::
F
,
2
));
ssound
.
samples
[
6
].
setPitch
(
Note
::
pitch
(
Tone
::
E
,
2
));
ssound
.
samples
[
7
].
setPitch
(
Note
::
pitch
(
Tone
::
D
,
2
));
ssound
.
samples
[
8
].
setPitch
(
Note
::
pitch
(
Tone
::
C
,
2
));
ssound
.
samples
[
9
].
setPitch
(
Note
::
pitch
(
Tone
::
C
,
2
));
ssound
.
samples
[
10
].
setPitch
(
Note
::
pitch
(
Tone
::
D
,
2
));
ssound
.
samples
[
11
].
setPitch
(
Note
::
pitch
(
Tone
::
E
,
2
));
ssound
.
samples
[
12
].
setPitch
(
Note
::
pitch
(
Tone
::
E
,
2
));
ssound
.
samples
[
13
].
setPitch
(
Note
::
pitch
(
Tone
::
D
,
2
));
for
(
size_t
i
=
0
;
i
<
ssound
.
samples
.
size
();
++
i
)
{
ssound
.
samples
[
i
].
setVolume
(
7
);
ssound
.
samples
[
i
].
setWaveform
(
Waveform
::
ORGAN
);
printf
(
"%d "
,
Note
::
frequency
(
ssound
.
samples
[
i
].
pitch
()));
}
sstate
.
sound
=
&
ssound
;
sstate
.
position
=
0
;
sstate
.
sample
=
0
;
SDL_PauseAudioDevice
(
device
,
false
);
}
void
APU
::
close
()
{
SDL_CloseAudioDevice
(
device
);
}
void
APU
::
renderSounds
(
int16_t
*
dest
,
size_t
samples
)
{
constexpr
size_t
rate
=
44100
;
size_t
samplePerTick
=
(
44100
/
128
)
*
(
sstate
.
sound
->
speed
+
1
);
while
(
samples
>
0
)
{
/* generate the maximum amount of samples available for same note */
// TODO: optimize if next note is equal to current
size_t
available
=
std
::
min
(
samples
,
samplePerTick
-
(
sstate
.
position
%
samplePerTick
));
const
SoundSample
&
sample
=
sstate
.
sound
->
samples
[
sstate
.
sample
];
/* render samples */
dsp
.
squareWave
(
Note
::
frequency
(
sample
.
pitch
()),
(
4096
/
8
)
*
sample
.
volume
(),
0
,
sstate
.
position
,
dest
,
samples
);
samples
-=
available
;
dest
+=
available
;
sstate
.
position
+=
available
;
sstate
.
sample
=
sstate
.
position
/
samplePerTick
;
}
}
\ No newline at end of file
src/vm/sound.h
View file @
e9fd1973
...
...
@@ -3,6 +3,7 @@
#include "defines.h"
#include "common.h"
#include <array>
#include <SDL_audio.h>
#if SOUND_ENABLED
...
...
@@ -13,6 +14,7 @@ namespace retro8
{
using
volume_t
=
int32_t
;
using
pitch_t
=
int32_t
;
using
frequency_t
=
int32_t
;
enum
class
Waveform
{
...
...
@@ -24,16 +26,44 @@ namespace retro8
NONE
,
SLIDE
,
VIBRATO
,
DROP
,
FADE_IN
,
FADE_OUT
,
ARPEGGIO_FAST
,
ARPEGGIO_SLOW
};
enum
class
Tone
{
C
,
CS
,
D
,
DS
,
E
,
F
,
FS
,
G
,
GS
,
A
,
AS
,
B
};
struct
Note
{
private:
constexpr
static
std
::
array
<
float
,
12
>
frequencies
=
{
130.81
f
,
138.59
f
,
146.83
f
,
155.56
f
,
164.81
f
,
174.61
f
,
185.00
f
,
196.00
,
207.65
,
220.0
,
233.08
,
246.94
};
public:
static
pitch_t
pitch
(
Tone
tone
,
int32_t
octave
=
1
)
{
return
pitch_t
(
tone
)
+
octave
*
12
;
}
static
frequency_t
frequency
(
Tone
tone
,
int32_t
octave
=
1
)
{
return
frequencies
[
size_t
(
tone
)]
*
octave
;
};
static
frequency_t
frequency
(
pitch_t
pitch
)
{
return
frequencies
[
pitch
%
12
]
*
(
1
+
pitch
/
12
);
}
};
struct
SoundSample
{
static
constexpr
uint16_t
EffectMask
=
0x7000
;
static
constexpr
uint16_t
VolumeMask
=
0x0E00
;
static
constexpr
uint16_t
WaveformMask
=
0x01C0
;
static
constexpr
uint16_t
PitchMask
=
0x003F
;
static
constexpr
uint32_t
EffectShift
=
12
;
static
constexpr
uint32_t
VolumeShift
=
9
;
static
constexpr
uint32_t
WaveformShift
=
6
;
//TODO: endianness is a fail here
uint16_t
value
;
bool
useSfx
()
const
{
return
value
&
0x8000
;
}
Effect
effect
()
const
{
return
Effect
((
value
>>
12
)
&
0b111
);
}
Waveform
waveform
()
const
{
return
Waveform
((
value
>>
6
)
&
0b111
);
}
volume_t
volume
()
const
{
return
(
value
>>
9
)
&
0b111
;
}
pitch_t
pitch
()
const
{
return
value
&
0x111111
;
}
Effect
effect
()
const
{
return
Effect
((
value
&
EffectMask
)
>>
EffectShift
);
}
Waveform
waveform
()
const
{
return
Waveform
((
value
&
WaveformMask
)
>>
WaveformShift
);
}
volume_t
volume
()
const
{
return
(
value
&
VolumeMask
)
>>
VolumeShift
;
}
pitch_t
pitch
()
const
{
return
value
&
PitchMask
;
}
void
setPitch
(
pitch_t
pitch
)
{
value
=
(
value
&
~
PitchMask
)
|
pitch
;
}
void
setVolume
(
volume_t
volume
)
{
value
=
(
value
&
~
VolumeMask
)
|
(
volume
<<
VolumeShift
);
}
void
setEffect
(
Effect
effect
)
{
value
=
(
value
&
~
EffectMask
)
|
(
uint16_t
(
effect
)
<<
EffectShift
);
}
void
setWaveform
(
Waveform
waveform
)
{
value
=
(
value
&
~
WaveformMask
)
|
(
uint16_t
(
waveform
)
<<
WaveformShift
);
}
};
struct
Sound
...
...
@@ -44,6 +74,13 @@ namespace retro8
uint8_t
loopStart
;
uint8_t
loopEnd
;
};
struct
SoundState
{
const
Sound
*
sound
;
uint32_t
sample
;
uint32_t
position
;
// absolute
};
class
DSP
{
...
...
@@ -77,6 +114,8 @@ namespace retro8
void
resume
();
void
pause
();
void
renderSounds
(
int16_t
*
dest
,
size_t
samples
);
};
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment