Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmeteor/source/audio/sound2.cpp
2 views
1
// Meteor - A Nintendo Gameboy Advance emulator
2
// Copyright (C) 2009-2011 Philippe Daouadi
3
//
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
#include "ameteor/audio/sound2.hpp"
18
#include "../globals.hpp"
19
#include <cmath>
20
21
namespace AMeteor
22
{
23
namespace Audio
24
{
25
Sound2::Sound2 (uint16_t& cntl, uint16_t& cnth, uint16_t freq) :
26
m_cntl(cntl),
27
m_cnth(cnth),
28
m_on(false),
29
m_posP(0),
30
m_posE(0),
31
m_sample(0),
32
m_speriod(16*1024*1024/freq),
33
m_envelope(0),
34
m_length(0),
35
m_timed(false)
36
{
37
}
38
39
void Sound2::Reset ()
40
{
41
m_on = false;
42
m_timed = false;
43
m_length = 0;
44
m_envelope = 0;
45
m_posP = m_posE = 0;
46
m_sample = 0;
47
}
48
49
void Sound2::ResetSound ()
50
{
51
m_on = true;
52
m_timed = (m_cnth & (0x1 << 14));
53
m_length = (64 - (m_cntl & 0x3F)) * ((16*1024*1024)/256);
54
m_envelope = m_cntl >> 12;
55
m_posE = 0;
56
}
57
58
void Sound2::SoundTick ()
59
{
60
// refer at sound1 to know how sound2 works
61
62
m_posP += m_speriod;
63
m_posE += m_speriod;
64
if (m_length > m_speriod)
65
m_length -= m_speriod;
66
else
67
{
68
if (m_timed)
69
m_on = false;
70
m_length = 0;
71
}
72
73
uint32_t period =
74
((16*1024*1024) / (128*1024)) * (2048 - (m_cnth & 0x7FF));
75
76
m_posP %= period;
77
78
uint32_t steptime = ((m_cntl >> 8) & 0x7) * ((16*1024*1024)/64);
79
if (steptime && m_posE > steptime)
80
{
81
if (m_cntl & (0x1 << 11))
82
{
83
if (m_envelope < 15)
84
++m_envelope;
85
}
86
else
87
{
88
if (m_envelope > 0)
89
--m_envelope;
90
}
91
92
m_posE -= steptime;
93
}
94
95
if (m_on && m_envelope)
96
{
97
switch ((m_cntl >> 6) & 0x3)
98
{
99
case 0: // 12.5%
100
m_sample = m_posP < period/8 ? 112 : -16;
101
break;
102
case 1: // 25%
103
m_sample = m_posP < period/4 ? 96 : -32;
104
break;
105
case 2: // 50%
106
m_sample = m_posP < period/2 ? 64 : -64;
107
break;
108
case 3: // 75%
109
m_sample = m_posP < (3*period)/4 ? 32 : -96;
110
break;
111
}
112
113
m_sample = (((int16_t)m_sample) * m_envelope)/15;
114
}
115
else
116
m_sample = 0;
117
}
118
119
bool Sound2::SaveState (std::ostream& stream)
120
{
121
SS_WRITE_VAR(m_on);
122
SS_WRITE_VAR(m_posP);
123
SS_WRITE_VAR(m_posE);
124
SS_WRITE_VAR(m_sample);
125
SS_WRITE_VAR(m_envelope);
126
SS_WRITE_VAR(m_length);
127
SS_WRITE_VAR(m_timed);
128
129
return true;
130
}
131
132
bool Sound2::LoadState (std::istream& stream)
133
{
134
SS_READ_VAR(m_on);
135
SS_READ_VAR(m_posP);
136
SS_READ_VAR(m_posE);
137
SS_READ_VAR(m_sample);
138
SS_READ_VAR(m_envelope);
139
SS_READ_VAR(m_length);
140
SS_READ_VAR(m_timed);
141
142
return true;
143
}
144
}
145
}
146
147