1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-09 06:29:33 +00:00

Made a very basic stab at a couple of the tone generators, added straight-through path for the speaker when input rate exactly equals output rate.

This commit is contained in:
Thomas Harte 2016-06-01 19:53:16 -04:00
parent 40c4544fb7
commit 1e0fcbbee8
3 changed files with 76 additions and 32 deletions

View File

@ -802,6 +802,7 @@ void Atari2600::Speaker::set_volume(int channel, uint8_t volume)
void Atari2600::Speaker::set_divider(int channel, uint8_t divider)
{
_divider[channel] = divider & 0x1f;
_divider_counter[channel] = 0;
}
void Atari2600::Speaker::set_control(int channel, uint8_t control)
@ -816,12 +817,21 @@ void Atari2600::Speaker::get_samples(unsigned int number_of_samples, int16_t *ta
target[c] = 0;
for(int channel = 0; channel < 2; channel++)
{
if(!_control[channel])
switch(_control[channel])
{
case 0x0: case 0xb:
target[c] += _volume[channel] * 1024;
}
else
{
break;
case 0x4: case 0x5:
_divider_counter[channel] ++;
target[c] += _volume[channel] * 1024 * ((_divider_counter[channel] / (_divider[channel]+1))&1);
break;
case 0xc: case 0xd:
_divider_counter[channel] ++;
target[c] += _volume[channel] * 1024 * ((_divider_counter[channel] / ((_divider[channel]+1)*3))&1);
break;
}
}
}

View File

@ -32,7 +32,9 @@ class Speaker: public ::Outputs::Filter<Speaker> {
uint8_t _volume[2];
uint8_t _divider[2];
uint8_t _control[2];
int _shift_counters[2];
int _shift_counter[2];
int _divider_counter[2];
int _output_state[2];
};
class Machine: public CPU6502::Processor<Machine>, public CRTMachine::Machine {

View File

@ -88,9 +88,36 @@ template <class T> class Filter: public Speaker {
{
if(_coefficients_are_dirty) update_filter_coefficients();
// TODO: what if output rate is greater than input rate?
// if input and output rates exactly match, just accumulate results and pass on
if(_input_cycles_per_second == _output_cycles_per_second)
{
while(input_cycles)
{
unsigned int cycles_to_read = (unsigned int)(_buffer_size - _buffer_in_progress_pointer);
if(cycles_to_read > input_cycles) cycles_to_read = input_cycles;
// fill up as much of the input buffer as possible
static_cast<T *>(this)->get_samples(cycles_to_read, &_buffer_in_progress.get()[_buffer_in_progress_pointer]);
_buffer_in_progress_pointer += cycles_to_read;
// announce to delegate if full
if(_buffer_in_progress_pointer == _buffer_size)
{
_buffer_in_progress_pointer = 0;
if(_delegate)
{
_delegate->speaker_did_complete_samples(this, _buffer_in_progress.get(), _buffer_size);
}
}
input_cycles -= cycles_to_read;
}
return;
}
// if the output rate is less than the input rate, use the filter
if(_input_cycles_per_second > _output_cycles_per_second)
{
while(input_cycles)
{
unsigned int cycles_to_read = (unsigned int)std::min((int)input_cycles, _number_of_taps - _input_buffer_depth);
@ -131,6 +158,11 @@ template <class T> class Filter: public Speaker {
}
}
}
return;
}
// TODO: input rate is less than output rate
}
private: