Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
folium-app
GitHub Repository: folium-app/Folium
Path: blob/a-new-beginning/Cherry/Core/Audio.cpp
2 views
1
/*
2
* Gearcoleco - ColecoVision Emulator
3
* Copyright (C) 2021 Ignacio Sanchez
4
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* any later version.
9
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
14
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see http://www.gnu.org/licenses/
17
*
18
*/
19
20
#include "Audio.h"
21
22
Audio::Audio()
23
{
24
m_ElapsedCycles = 0;
25
m_iSampleRate = GC_AUDIO_SAMPLE_RATE;
26
InitPointer(m_pApu);
27
InitPointer(m_pBuffer);
28
InitPointer(m_pSampleBuffer);
29
m_bPAL = false;
30
InitPointer(m_pAY8910);
31
InitPointer(m_pSGMBuffer);
32
m_bMute = false;
33
m_bVgmRecordingEnabled = false;
34
m_AY8910Register = 0;
35
}
36
37
Audio::~Audio()
38
{
39
SafeDelete(m_pApu);
40
SafeDelete(m_pBuffer);
41
SafeDeleteArray(m_pSampleBuffer);
42
SafeDelete(m_pAY8910);
43
SafeDeleteArray(m_pSGMBuffer);
44
}
45
46
void Audio::Init()
47
{
48
m_pSampleBuffer = new blip_sample_t[GC_AUDIO_BUFFER_SIZE];
49
50
m_pApu = new Sms_Apu();
51
m_pBuffer = new Stereo_Buffer();
52
53
m_pBuffer->clock_rate(m_bPAL ? GC_MASTER_CLOCK_PAL : GC_MASTER_CLOCK_NTSC);
54
m_pBuffer->set_sample_rate(m_iSampleRate);
55
56
//m_pApu->treble_eq(-15.0);
57
//m_pBuffer->bass_freq(100);
58
59
m_pApu->output(m_pBuffer->center(), m_pBuffer->left(), m_pBuffer->right());
60
m_pApu->volume(0.6);
61
62
m_pSGMBuffer = new s16[GC_AUDIO_BUFFER_SIZE];
63
64
m_pAY8910 = new AY8910();
65
m_pAY8910->Init(m_bPAL ? GC_MASTER_CLOCK_PAL : GC_MASTER_CLOCK_NTSC);
66
}
67
68
void Audio::Reset(bool bPAL)
69
{
70
m_bPAL = bPAL;
71
m_pApu->reset();
72
m_pApu->volume(0.6);
73
m_pBuffer->clear();
74
m_pBuffer->clock_rate(m_bPAL ? GC_MASTER_CLOCK_PAL : GC_MASTER_CLOCK_NTSC);
75
m_ElapsedCycles = 0;
76
m_pAY8910->Reset(m_bPAL ? GC_MASTER_CLOCK_PAL : GC_MASTER_CLOCK_NTSC);
77
}
78
79
void Audio::Mute(bool mute)
80
{
81
m_bMute = mute;
82
}
83
84
void Audio::EndFrame(s16* pSampleBuffer, int* pSampleCount)
85
{
86
m_pApu->end_frame((blip_time_t)m_ElapsedCycles);
87
m_pBuffer->end_frame((blip_time_t)m_ElapsedCycles);
88
89
int count = static_cast<int>(m_pBuffer->read_samples(m_pSampleBuffer, GC_AUDIO_BUFFER_SIZE));
90
91
m_pAY8910->EndFrame(m_pSGMBuffer);
92
93
if (IsValidPointer(pSampleBuffer) && IsValidPointer(pSampleCount))
94
{
95
*pSampleCount = count;
96
97
for (int i=0; i<count; i++)
98
{
99
if (m_bMute)
100
pSampleBuffer[i] = 0;
101
else
102
pSampleBuffer[i] = m_pSampleBuffer[i] + m_pSGMBuffer[i];
103
}
104
}
105
106
#ifndef GEARCOLECO_DISABLE_VGMRECORDER
107
if (m_bVgmRecordingEnabled)
108
m_VgmRecorder.UpdateTiming(count / 2);
109
#endif
110
111
m_ElapsedCycles = 0;
112
}
113
114
void Audio::SaveState(std::ostream& stream)
115
{
116
stream.write(reinterpret_cast<const char*> (&m_ElapsedCycles), sizeof(m_ElapsedCycles));
117
stream.write(reinterpret_cast<const char*> (m_pSampleBuffer), sizeof(blip_sample_t) * GC_AUDIO_BUFFER_SIZE);
118
stream.write(reinterpret_cast<const char*> (m_pSGMBuffer), sizeof(s16) * GC_AUDIO_BUFFER_SIZE);
119
m_pAY8910->SaveState(stream);
120
}
121
122
void Audio::LoadState(std::istream& stream)
123
{
124
stream.read(reinterpret_cast<char*> (&m_ElapsedCycles), sizeof(m_ElapsedCycles));
125
stream.read(reinterpret_cast<char*> (m_pSampleBuffer), sizeof(blip_sample_t) * GC_AUDIO_BUFFER_SIZE);
126
stream.read(reinterpret_cast<char*> (m_pSGMBuffer), sizeof(s16) * GC_AUDIO_BUFFER_SIZE);
127
m_pAY8910->LoadState(stream);
128
129
m_pApu->reset();
130
m_pApu->volume(0.6);
131
m_pBuffer->clear();
132
}
133
134
bool Audio::StartVgmRecording(const char* file_path, int clock_rate, bool is_pal)
135
{
136
if (m_bVgmRecordingEnabled)
137
return false;
138
139
m_VgmRecorder.Start(file_path, clock_rate, is_pal);
140
m_bVgmRecordingEnabled = m_VgmRecorder.IsRecording();
141
return m_bVgmRecordingEnabled;
142
}
143
144
void Audio::StopVgmRecording()
145
{
146
if (m_bVgmRecordingEnabled)
147
{
148
m_VgmRecorder.Stop();
149
m_bVgmRecordingEnabled = false;
150
}
151
}
152
153
bool Audio::IsVgmRecording() const
154
{
155
return m_bVgmRecordingEnabled;
156
}
157
158