mirror of
https://github.com/TomHarte/CLK.git
synced 2024-10-06 15:00:05 +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:
parent
40c4544fb7
commit
1e0fcbbee8
@ -802,6 +802,7 @@ void Atari2600::Speaker::set_volume(int channel, uint8_t volume)
|
|||||||
void Atari2600::Speaker::set_divider(int channel, uint8_t divider)
|
void Atari2600::Speaker::set_divider(int channel, uint8_t divider)
|
||||||
{
|
{
|
||||||
_divider[channel] = divider & 0x1f;
|
_divider[channel] = divider & 0x1f;
|
||||||
|
_divider_counter[channel] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Atari2600::Speaker::set_control(int channel, uint8_t control)
|
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;
|
target[c] = 0;
|
||||||
for(int channel = 0; channel < 2; channel++)
|
for(int channel = 0; channel < 2; channel++)
|
||||||
{
|
{
|
||||||
if(!_control[channel])
|
switch(_control[channel])
|
||||||
{
|
{
|
||||||
|
case 0x0: case 0xb:
|
||||||
target[c] += _volume[channel] * 1024;
|
target[c] += _volume[channel] * 1024;
|
||||||
}
|
break;
|
||||||
else
|
|
||||||
{
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,9 @@ class Speaker: public ::Outputs::Filter<Speaker> {
|
|||||||
uint8_t _volume[2];
|
uint8_t _volume[2];
|
||||||
uint8_t _divider[2];
|
uint8_t _divider[2];
|
||||||
uint8_t _control[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 {
|
class Machine: public CPU6502::Processor<Machine>, public CRTMachine::Machine {
|
||||||
|
@ -88,9 +88,36 @@ template <class T> class Filter: public Speaker {
|
|||||||
{
|
{
|
||||||
if(_coefficients_are_dirty) update_filter_coefficients();
|
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)
|
while(input_cycles)
|
||||||
{
|
{
|
||||||
unsigned int cycles_to_read = (unsigned int)std::min((int)input_cycles, _number_of_taps - _input_buffer_depth);
|
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:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user