2 #include "romimage.hpp"
5 #include "instance.hpp"
6 #include "library/string.hpp"
7 #include "library/zip.hpp"
8 #include "library/minmax.hpp"
20 sound::sound(struct sounds
& _snds
, uint8_t _rate
, uint32_t ptr
, uint32_t len
)
32 sounds::sounds(const std::vector
<char>& snd
, size_t samples
)
36 if(snd
.size() < 2 * samples
+ 2)
37 (stringfmt() << "Sound pointer table incomplete").throwex();
38 for(unsigned i
= 0; i
< samples
; i
++) {
39 size_t sptr
= combine(snd
[2 * i
+ 0], snd
[2 * i
+ 1]);
40 size_t eptr
= combine(snd
[2 * i
+ 2], snd
[2 * i
+ 3]);
41 if(sptr
>= snd
.size())
42 (stringfmt() << "Sound " << i
<< " points outside file").throwex();
44 (stringfmt() << "Sound " << i
<< " extends past the end of file").throwex();
46 (stringfmt() << "Sound " << i
<< " size invalid (must be >0)").throwex();
47 uint8_t rate
= snd
[sptr
];
48 sfx
[i
] = sound(*this, rate
, sptr
+ 1, eptr
- sptr
- 1);
52 sounds::sounds(const sounds
& s
)
57 sounds
& sounds::operator=(const sounds
& s
)
61 sounddata
= s
.sounddata
;
62 sfx
.resize(s
.sfx
.size());
63 for(unsigned i
= 0; i
< s
.sfx
.size(); i
++)
64 sfx
[i
] = sound(*this, s
.sfx
[i
].get_rate(), s
.sfx
[i
].get_pointer(), s
.sfx
[i
].get_length());
68 active_sfx_dma::active_sfx_dma()
79 void active_sfx_dma::reset(const struct sound
& snd
)
81 rate
= snd
.get_rate();
82 left
= 48000ULL * (256 - rate
) * snd
.get_length();
84 pointer
= snd
.get_pointer();
85 mdr
= access(snd
.get_sounds(), pointer
++);
88 void active_sfx_dma::fetch(struct sounds
& snds
, int16_t* buffer
, size_t samples
)
90 while(left
> 0 && samples
> 0) {
91 *(buffer
++) = 256 * ((int16_t)mdr
- 128);
92 *(buffer
++) = 256 * ((int16_t)mdr
- 128);
94 while(subsample
> 48000ULL * (256 - rate
)) {
95 mdr
= snds
.access(pointer
++);
96 subsample
-= 48000ULL * (256 - rate
);
101 //Fill the rest with silence.
102 for(size_t i
= 0; i
< samples
; i
++) {
108 void fetch_sfx(struct instance
& inst
, int16_t* buffer
, size_t samples
)
110 std::vector
<std::pair
<int16_t, int16_t>> buf
;
112 inst
.state
.dma
.fetch(inst
.soundfx
, buffer
, samples
);
114 inst
.mplayer
.decode(&buf
[0], samples
);
117 for(size_t i
= 0; i
< samples
; i
++) {
118 buffer
[2 * i
+ 0] = max(min((int32_t)buffer
[2 * i
+ 0] + buf
[i
].first
, 32767), -32768);
119 buffer
[2 * i
+ 1] = max(min((int32_t)buffer
[2 * i
+ 1] + buf
[i
].second
, 32767), -32768);
124 sound_noise_maker::sound_noise_maker(const sounds
& _snds
, struct active_sfx_dma
& _dma
)
125 : snds(_snds
), dma(_dma
)
129 sound_noise_maker::~sound_noise_maker() {}
130 void sound_noise_maker::operator()(int sound
, bool hipri
)
132 if(!hipri
&& dma
.hipri() && dma
.busy())
134 dma
.reset(snds
[sound
]);