~ubuntu-branches/ubuntu/wily/xmms2/wily

« back to all changes in this revision

Viewing changes to src/plugins/gme/gme/Kss_Scc_Apu.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Benjamin Drung
  • Date: 2008-07-04 16:23:34 UTC
  • mfrom: (1.1.5 upstream) (6.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080704162334-b3esbkcapt8wbrk4
Tags: 0.5DrLecter-2ubuntu1
* Merge from debian unstable (LP: #241098), remaining changes:
  + debian/control:
    + Update Maintainer field
    + add lpia to xmms2-plugin-alsa supported architectures
    + Added liba52-0.7.4-dev to build depends
  + debian/rules: Added patch, patch-stamp and unpatch
  + changed 01_gcc4.3.patch:
    + src/include/xmmsclient/xmmsclient++/helpers.h: Added #include <climits>
* New upstream relase fixes LP: #212566, #222341

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
 
2
 
 
3
#include "Kss_Scc_Apu.h"
 
4
 
 
5
/* Copyright (C) 2006 Shay Green. This module is free software; you
 
6
can redistribute it and/or modify it under the terms of the GNU Lesser
 
7
General Public License as published by the Free Software Foundation; either
 
8
version 2.1 of the License, or (at your option) any later version. This
 
9
module is distributed in the hope that it will be useful, but WITHOUT ANY
 
10
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
11
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 
12
details. You should have received a copy of the GNU Lesser General Public
 
13
License along with this module; if not, write to the Free Software Foundation,
 
14
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
 
15
 
 
16
#include "blargg_source.h"
 
17
 
 
18
// Tones above this frequency are treated as disabled tone at half volume.
 
19
// Power of two is more efficient (avoids division).
 
20
unsigned const inaudible_freq = 16384;
 
21
 
 
22
int const wave_size = 0x20;
 
23
 
 
24
void Scc_Apu::run_until( blip_time_t end_time )
 
25
{
 
26
        for ( int index = 0; index < osc_count; index++ )
 
27
        {
 
28
                osc_t& osc = oscs [index];
 
29
                
 
30
                Blip_Buffer* const output = osc.output;
 
31
                if ( !output )
 
32
                        continue;
 
33
                output->set_modified();
 
34
                
 
35
                blip_time_t period = (regs [0x80 + index * 2 + 1] & 0x0F) * 0x100 +
 
36
                                regs [0x80 + index * 2] + 1;
 
37
                int volume = 0;
 
38
                if ( regs [0x8F] & (1 << index) )
 
39
                {
 
40
                        blip_time_t inaudible_period = (blargg_ulong) (output->clock_rate() +
 
41
                                        inaudible_freq * 32) / (inaudible_freq * 16);
 
42
                        if ( period > inaudible_period )
 
43
                                volume = (regs [0x8A + index] & 0x0F) * (amp_range / 256 / 15);
 
44
                }
 
45
                
 
46
                BOOST::int8_t const* wave = (BOOST::int8_t*) regs + index * wave_size;
 
47
                if ( index == osc_count - 1 )
 
48
                        wave -= wave_size; // last two oscs share wave
 
49
                {
 
50
                        int amp = wave [osc.phase] * volume;
 
51
                        int delta = amp - osc.last_amp;
 
52
                        if ( delta )
 
53
                        {
 
54
                                osc.last_amp = amp;
 
55
                                synth.offset( last_time, delta, output );
 
56
                        }
 
57
                }
 
58
                
 
59
                blip_time_t time = last_time + osc.delay;
 
60
                if ( time < end_time )
 
61
                {
 
62
                        if ( !volume )
 
63
                        {
 
64
                                // maintain phase
 
65
                                blargg_long count = (end_time - time + period - 1) / period;
 
66
                                osc.phase = (osc.phase + count) & (wave_size - 1);
 
67
                                time += count * period;
 
68
                        }
 
69
                        else
 
70
                        {
 
71
                                
 
72
                                int phase = osc.phase;
 
73
                                int last_wave = wave [phase];
 
74
                                phase = (phase + 1) & (wave_size - 1); // pre-advance for optimal inner loop
 
75
                                
 
76
                                do
 
77
                                {
 
78
                                        int amp = wave [phase];
 
79
                                        phase = (phase + 1) & (wave_size - 1);
 
80
                                        int delta = amp - last_wave;
 
81
                                        if ( delta )
 
82
                                        {
 
83
                                                last_wave = amp;
 
84
                                                synth.offset( time, delta * volume, output );
 
85
                                        }
 
86
                                        time += period;
 
87
                                }
 
88
                                while ( time < end_time );
 
89
                                
 
90
                                osc.phase = phase = (phase - 1) & (wave_size - 1); // undo pre-advance
 
91
                                osc.last_amp = wave [phase] * volume;
 
92
                        }
 
93
                }
 
94
                osc.delay = time - end_time;
 
95
        }
 
96
        last_time = end_time;
 
97
}