"Fossies" - the Fresh Open Source Software Archive

Member "audacious-plugins-3.10.1/src/console/Nes_Fme7_Apu.cc" (26 Dec 2018, 3307 Bytes) of package /linux/misc/audacious-plugins-3.10.1.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "Nes_Fme7_Apu.cc" see the Fossies "Dox" file reference documentation.

    1 // Game_Music_Emu 0.5.5. http://www.slack.net/~ant/
    2 
    3 #include "Nes_Fme7_Apu.h"
    4 
    5 #include <string.h>
    6 
    7 /* Copyright (C) 2003-2006 Shay Green. This module is free software; you
    8 can redistribute it and/or modify it under the terms of the GNU Lesser
    9 General Public License as published by the Free Software Foundation; either
   10 version 2.1 of the License, or (at your option) any later version. This
   11 module is distributed in the hope that it will be useful, but WITHOUT ANY
   12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   13 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
   14 details. You should have received a copy of the GNU Lesser General Public
   15 License along with this module; if not, write to the Free Software Foundation,
   16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
   17 
   18 #include "blargg_source.h"
   19 
   20 void Nes_Fme7_Apu::reset()
   21 {
   22     last_time = 0;
   23 
   24     for ( int i = 0; i < osc_count; i++ )
   25         oscs [i].last_amp = 0;
   26 
   27     fme7_apu_state_t* state = this;
   28     memset( state, 0, sizeof *state );
   29 }
   30 
   31 unsigned char const Nes_Fme7_Apu::amp_table [16] =
   32 {
   33     #define ENTRY( n ) (unsigned char) (n * amp_range + 0.5)
   34     ENTRY(0.0000), ENTRY(0.0078), ENTRY(0.0110), ENTRY(0.0156),
   35     ENTRY(0.0221), ENTRY(0.0312), ENTRY(0.0441), ENTRY(0.0624),
   36     ENTRY(0.0883), ENTRY(0.1249), ENTRY(0.1766), ENTRY(0.2498),
   37     ENTRY(0.3534), ENTRY(0.4998), ENTRY(0.7070), ENTRY(1.0000)
   38     #undef ENTRY
   39 };
   40 
   41 void Nes_Fme7_Apu::run_until( blip_time_t end_time )
   42 {
   43     require( end_time >= last_time );
   44 
   45     for ( int index = 0; index < osc_count; index++ )
   46     {
   47         int mode = regs [7] >> index;
   48         int vol_mode = regs [010 + index];
   49         int volume = amp_table [vol_mode & 0x0F];
   50 
   51         Blip_Buffer* const osc_output = oscs [index].output;
   52         if ( !osc_output )
   53             continue;
   54         osc_output->set_modified();
   55 
   56         // check for unsupported mode
   57         #ifndef NDEBUG
   58             if ( (mode & 011) <= 001 && vol_mode & 0x1F )
   59                 debug_printf( "FME7 used unimplemented sound mode: %02X, vol_mode: %02X\n",
   60                         mode, vol_mode & 0x1F );
   61         #endif
   62 
   63         if ( (mode & 001) | (vol_mode & 0x10) )
   64             volume = 0; // noise and envelope aren't supported
   65 
   66         // period
   67         int const period_factor = 16;
   68         unsigned period = (regs [index * 2 + 1] & 0x0F) * 0x100 * period_factor +
   69                 regs [index * 2] * period_factor;
   70         if ( period < 50 ) // around 22 kHz
   71         {
   72             volume = 0;
   73             if ( !period ) // on my AY-3-8910A, period doesn't have extra one added
   74                 period = period_factor;
   75         }
   76 
   77         // current amplitude
   78         int amp = volume;
   79         if ( !phases [index] )
   80             amp = 0;
   81         {
   82             int delta = amp - oscs [index].last_amp;
   83             if ( delta )
   84             {
   85                 oscs [index].last_amp = amp;
   86                 synth.offset( last_time, delta, osc_output );
   87             }
   88         }
   89 
   90         blip_time_t time = last_time + delays [index];
   91         if ( time < end_time )
   92         {
   93             int delta = amp * 2 - volume;
   94             if ( volume )
   95             {
   96                 do
   97                 {
   98                     delta = -delta;
   99                     synth.offset_inline( time, delta, osc_output );
  100                     time += period;
  101                 }
  102                 while ( time < end_time );
  103 
  104                 oscs [index].last_amp = (delta + volume) >> 1;
  105                 phases [index] = (delta > 0);
  106             }
  107             else
  108             {
  109                 // maintain phase when silent
  110                 int count = (end_time - time + period - 1) / period;
  111                 phases [index] ^= count & 1;
  112                 time += (blargg_long) count * period;
  113             }
  114         }
  115 
  116         delays [index] = time - end_time;
  117     }
  118 
  119     last_time = end_time;
  120 }
  121