mirror of
https://github.com/LMMS/lmms.git
synced 2026-04-07 23:58:22 -04:00
Refactor/subclass Basic_Gb_Apu
This commit is contained in:
@@ -1,79 +0,0 @@
|
||||
|
||||
// Gb_Snd_Emu 0.1.4. http://www.slack.net/~ant/libs/
|
||||
|
||||
#include "Basic_Gb_Apu.h"
|
||||
|
||||
/* Copyright (C) 2003-2005 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
|
||||
more details. You should have received a copy of the GNU Lesser General
|
||||
Public License along with this module; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
blip_time_t const frame_length = 70224;
|
||||
|
||||
Basic_Gb_Apu::Basic_Gb_Apu()
|
||||
{
|
||||
time = 0;
|
||||
}
|
||||
|
||||
Basic_Gb_Apu::~Basic_Gb_Apu()
|
||||
{
|
||||
}
|
||||
|
||||
blargg_err_t Basic_Gb_Apu::set_sample_rate( long rate )
|
||||
{
|
||||
apu.output( buf.center(), buf.left(), buf.right() );
|
||||
buf.clock_rate( 4194304 );
|
||||
return buf.set_sample_rate( rate );
|
||||
}
|
||||
|
||||
void Basic_Gb_Apu::write_register( blip_time_t addr, int data )
|
||||
{
|
||||
apu.write_register( clock(), addr, data );
|
||||
}
|
||||
|
||||
int Basic_Gb_Apu::read_register( blip_time_t addr )
|
||||
{
|
||||
return apu.read_register( clock(), addr );
|
||||
}
|
||||
|
||||
void Basic_Gb_Apu::end_frame()
|
||||
{
|
||||
time = 0;
|
||||
apu.end_frame( frame_length );
|
||||
buf.end_frame( frame_length );
|
||||
}
|
||||
|
||||
long Basic_Gb_Apu::samples_avail() const
|
||||
{
|
||||
return buf.samples_avail();
|
||||
}
|
||||
|
||||
long Basic_Gb_Apu::read_samples( sample_t* out, long count )
|
||||
{
|
||||
return buf.read_samples( out, count );
|
||||
}
|
||||
|
||||
//added by 589 --->
|
||||
|
||||
void Basic_Gb_Apu::reset()
|
||||
{
|
||||
apu.reset();
|
||||
}
|
||||
|
||||
void Basic_Gb_Apu::treble_eq( const blip_eq_t& eq )
|
||||
{
|
||||
apu.treble_eq( eq );
|
||||
}
|
||||
|
||||
void Basic_Gb_Apu::bass_freq( int bf )
|
||||
{
|
||||
buf.bass_freq( bf );
|
||||
}
|
||||
|
||||
// <---
|
||||
@@ -1,55 +0,0 @@
|
||||
|
||||
// Simplified Nintendo Game Boy PAPU sound chip emulator
|
||||
|
||||
// Gb_Snd_Emu 0.1.4. Copyright (C) 2003-2005 Shay Green. GNU LGPL license.
|
||||
|
||||
#ifndef BASIC_GB_APU_H
|
||||
#define BASIC_GB_APU_H
|
||||
|
||||
#include "Gb_Apu.h"
|
||||
#include "Multi_Buffer.h"
|
||||
#include "MemoryManager.h"
|
||||
|
||||
class Basic_Gb_Apu {
|
||||
MM_OPERATORS
|
||||
public:
|
||||
Basic_Gb_Apu();
|
||||
~Basic_Gb_Apu();
|
||||
|
||||
// Set output sample rate
|
||||
blargg_err_t set_sample_rate( long rate );
|
||||
|
||||
// Pass reads and writes in the range 0xff10-0xff3f
|
||||
void write_register( blip_time_t, int data );
|
||||
int read_register( blip_time_t );
|
||||
|
||||
// End a 1/60 sound frame and add samples to buffer
|
||||
void end_frame();
|
||||
|
||||
// Samples are generated in stereo, left first. Sample counts are always
|
||||
// a multiple of 2.
|
||||
|
||||
// Number of samples in buffer
|
||||
long samples_avail() const;
|
||||
|
||||
// Read at most 'count' samples out of buffer and return number actually read
|
||||
typedef blip_sample_t sample_t;
|
||||
long read_samples( sample_t* out, long count );
|
||||
|
||||
//added by 589 --->
|
||||
void reset();
|
||||
void treble_eq( const blip_eq_t& eq );
|
||||
void bass_freq( int bf );
|
||||
//<---
|
||||
|
||||
private:
|
||||
Gb_Apu apu;
|
||||
Stereo_Buffer buf;
|
||||
blip_time_t time;
|
||||
|
||||
// faked CPU timing
|
||||
blip_time_t clock() { return time += 4; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,10 +6,8 @@ INCLUDE_DIRECTORIES(game-music-emu/gme)
|
||||
BUILD_PLUGIN(papu
|
||||
papu_instrument.cpp
|
||||
papu_instrument.h
|
||||
Basic_Gb_Apu.cpp # TODO: Replace with subclass
|
||||
Basic_Gb_Apu.h # TODO: Replace with subclass
|
||||
# Gb_Apu_Buffer.cpp
|
||||
# Gb_Apu_Buffer.h
|
||||
Gb_Apu_Buffer.cpp
|
||||
Gb_Apu_Buffer.h
|
||||
game-music-emu/gme/Gb_Apu.cpp
|
||||
game-music-emu/gme/Gb_Apu.h
|
||||
game-music-emu/gme/Gb_Oscs.cpp
|
||||
|
||||
66
plugins/papu/Gb_Apu_Buffer.cpp
Normal file
66
plugins/papu/Gb_Apu_Buffer.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Gb_Apu_Buffer.cpp - Gb_Apu subclass which allows direct buffer access
|
||||
* Copyright (c) 2017 Tres Finocchiaro <tres.finocchiaro/at/gmail.com>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
#include "Gb_Apu.h"
|
||||
#include "Gb_Apu_Buffer.h"
|
||||
|
||||
blip_time_t const FRAME_LENGTH = 70224;
|
||||
long const CLOCK_RATE = 4194304;
|
||||
|
||||
Gb_Apu_Buffer::Gb_Apu_Buffer() : m_time(0) {}
|
||||
Gb_Apu_Buffer::~Gb_Apu_Buffer() {}
|
||||
|
||||
void Gb_Apu_Buffer::write_register(blip_time_t ignore, unsigned addr, int data) {
|
||||
Gb_Apu::write_register(clock(), addr, data);
|
||||
}
|
||||
|
||||
int Gb_Apu_Buffer::read_register(blip_time_t ignore, unsigned addr) {
|
||||
return Gb_Apu::read_register(clock(), addr);
|
||||
}
|
||||
|
||||
void Gb_Apu_Buffer::end_frame(blip_time_t ignore) {
|
||||
m_time = 0;
|
||||
Gb_Apu::end_frame(FRAME_LENGTH);
|
||||
m_buf.end_frame(FRAME_LENGTH);
|
||||
}
|
||||
|
||||
// Sets specified sample rate and hard-coded clock rate in Multi_Buffer
|
||||
blargg_err_t Gb_Apu_Buffer::set_sample_rate(long rate) {
|
||||
Gb_Apu_Buffer::output(m_buf.center(), m_buf.left(), m_buf.right());
|
||||
m_buf.clock_rate(CLOCK_RATE);
|
||||
return m_buf.set_sample_rate(rate);
|
||||
}
|
||||
|
||||
// Wrap Multi_Buffer::samples_avail()
|
||||
long Gb_Apu_Buffer::samples_avail() const {
|
||||
return m_buf.samples_avail();
|
||||
}
|
||||
|
||||
// Wrap Multi_Buffer::read_samples(...)
|
||||
long Gb_Apu_Buffer::read_samples(sample_t* out, long count) {
|
||||
return m_buf.read_samples(out, count);
|
||||
}
|
||||
|
||||
void Gb_Apu_Buffer::bass_freq(int freq) {
|
||||
m_buf.bass_freq(freq);
|
||||
}
|
||||
|
||||
54
plugins/papu/Gb_Apu_Buffer.h
Normal file
54
plugins/papu/Gb_Apu_Buffer.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Gb_Apu_Buffer.cpp - Gb_Apu subclass which allows direct buffer access
|
||||
* Copyright (c) 2017 Tres Finocchiaro <tres.finocchiaro/at/gmail.com>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
#ifndef GB_APU_BUFFER_H
|
||||
#define GB_APU_BUFFER_H
|
||||
|
||||
#include "Gb_Apu.h"
|
||||
#include "Multi_Buffer.h"
|
||||
#include "MemoryManager.h"
|
||||
|
||||
class Gb_Apu_Buffer : public Gb_Apu {
|
||||
MM_OPERATORS
|
||||
public:
|
||||
Gb_Apu_Buffer();
|
||||
~Gb_Apu_Buffer();
|
||||
|
||||
void write_register(blip_time_t, unsigned addr, int data);
|
||||
int read_register(blip_time_t, unsigned addr);
|
||||
void end_frame(blip_time_t);
|
||||
blargg_err_t set_sample_rate(long rate);
|
||||
long samples_avail() const;
|
||||
typedef blip_sample_t sample_t;
|
||||
long read_samples(sample_t* out, long count);
|
||||
|
||||
void bass_freq(int freq);
|
||||
private:
|
||||
Stereo_Buffer m_buf;
|
||||
blip_time_t m_time;
|
||||
|
||||
// faked CPU timing
|
||||
blip_time_t clock() { return m_time += 4; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
|
||||
#include <QPainter>
|
||||
#include <QDomElement>
|
||||
#include "Basic_Gb_Apu.h"
|
||||
|
||||
#include "papu_instrument.h"
|
||||
#include "Gb_Apu_Buffer.h"
|
||||
#include "Multi_Buffer.h"
|
||||
#include "base64.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "Knob.h"
|
||||
@@ -248,25 +248,25 @@ void papuInstrument::playNote( NotePlayHandle * _n,
|
||||
|
||||
if ( tfp == 0 )
|
||||
{
|
||||
Basic_Gb_Apu *papu = new Basic_Gb_Apu();
|
||||
Gb_Apu_Buffer *papu = new Gb_Apu_Buffer();
|
||||
papu->set_sample_rate( samplerate );
|
||||
|
||||
// Master sound circuitry power control
|
||||
papu->write_register( 0xff26, 0x80 );
|
||||
papu->write_register( 0, 0xff26, 0x80 );
|
||||
|
||||
data = m_ch1VolumeModel.value();
|
||||
data = data<<1;
|
||||
data += m_ch1VolSweepDirModel.value();
|
||||
data = data<<3;
|
||||
data += m_ch1SweepStepLengthModel.value();
|
||||
papu->write_register( 0xff12, data );
|
||||
papu->write_register( 0, 0xff12, data );
|
||||
|
||||
data = m_ch2VolumeModel.value();
|
||||
data = data<<1;
|
||||
data += m_ch2VolSweepDirModel.value();
|
||||
data = data<<3;
|
||||
data += m_ch2SweepStepLengthModel.value();
|
||||
papu->write_register( 0xff17, data );
|
||||
papu->write_register( 0, 0xff17, data );
|
||||
|
||||
//channel 4 - noise
|
||||
data = m_ch4VolumeModel.value();
|
||||
@@ -274,15 +274,15 @@ void papuInstrument::playNote( NotePlayHandle * _n,
|
||||
data += m_ch4VolSweepDirModel.value();
|
||||
data = data<<3;
|
||||
data += m_ch4SweepStepLengthModel.value();
|
||||
papu->write_register( 0xff21, data );
|
||||
papu->write_register( 0, 0xff21, data );
|
||||
|
||||
//channel 4 init
|
||||
papu->write_register( 0xff23, 128 );
|
||||
papu->write_register( 0, 0xff23, 128 );
|
||||
|
||||
_n->m_pluginData = papu;
|
||||
}
|
||||
|
||||
Basic_Gb_Apu *papu = static_cast<Basic_Gb_Apu *>( _n->m_pluginData );
|
||||
Gb_Apu_Buffer *papu = static_cast<Gb_Apu_Buffer *>( _n->m_pluginData );
|
||||
|
||||
papu->treble_eq( m_trebleModel.value() );
|
||||
papu->bass_freq( m_bassModel.value() );
|
||||
@@ -293,35 +293,35 @@ void papuInstrument::playNote( NotePlayHandle * _n,
|
||||
data += m_ch1SweepDirModel.value();
|
||||
data = data << 3;
|
||||
data += m_ch1SweepRtShiftModel.value();
|
||||
papu->write_register( 0xff10, data );
|
||||
papu->write_register( 0, 0xff10, data );
|
||||
|
||||
data = m_ch1WavePatternDutyModel.value();
|
||||
data = data<<6;
|
||||
papu->write_register( 0xff11, data );
|
||||
papu->write_register( 0, 0xff11, data );
|
||||
|
||||
|
||||
//channel 2 - square
|
||||
data = m_ch2WavePatternDutyModel.value();
|
||||
data = data<<6;
|
||||
papu->write_register( 0xff16, data );
|
||||
papu->write_register( 0, 0xff16, data );
|
||||
|
||||
|
||||
//channel 3 - wave
|
||||
//data = m_ch3OnModel.value()?128:0;
|
||||
data = 128;
|
||||
papu->write_register( 0xff1a, data );
|
||||
papu->write_register( 0, 0xff1a, data );
|
||||
|
||||
int ch3voldata[4] = { 0, 3, 2, 1 };
|
||||
data = ch3voldata[(int)m_ch3VolumeModel.value()];
|
||||
data = data<<5;
|
||||
papu->write_register( 0xff1c, data );
|
||||
papu->write_register( 0, 0xff1c, data );
|
||||
|
||||
|
||||
//controls
|
||||
data = m_so1VolumeModel.value();
|
||||
data = data<<4;
|
||||
data += m_so2VolumeModel.value();
|
||||
papu->write_register( 0xff24, data );
|
||||
papu->write_register( 0, 0xff24, data );
|
||||
|
||||
data = m_ch4So2Model.value()?128:0;
|
||||
data += m_ch3So2Model.value()?64:0;
|
||||
@@ -331,7 +331,7 @@ void papuInstrument::playNote( NotePlayHandle * _n,
|
||||
data += m_ch3So1Model.value()?4:0;
|
||||
data += m_ch2So1Model.value()?2:0;
|
||||
data += m_ch1So1Model.value()?1:0;
|
||||
papu->write_register( 0xff25, data );
|
||||
papu->write_register( 0, 0xff25, data );
|
||||
|
||||
const float * wpm = m_graphModel.samples();
|
||||
|
||||
@@ -339,7 +339,7 @@ void papuInstrument::playNote( NotePlayHandle * _n,
|
||||
{
|
||||
data = (int)floor(wpm[i*2]) << 4;
|
||||
data += (int)floor(wpm[i*2+1]);
|
||||
papu->write_register( 0xff30 + i, data );
|
||||
papu->write_register( 0, 0xff30 + i, data );
|
||||
}
|
||||
|
||||
if( ( freq >= 65 ) && ( freq <=4000 ) )
|
||||
@@ -349,13 +349,13 @@ void papuInstrument::playNote( NotePlayHandle * _n,
|
||||
data = 2048 - ( ( 4194304 / freq )>>5 );
|
||||
if( tfp==0 )
|
||||
{
|
||||
papu->write_register( 0xff13, data & 0xff );
|
||||
papu->write_register( 0xff14, (data>>8) | initflag );
|
||||
papu->write_register( 0, 0xff13, data & 0xff );
|
||||
papu->write_register( 0, 0xff14, (data>>8) | initflag );
|
||||
}
|
||||
papu->write_register( 0xff18, data & 0xff );
|
||||
papu->write_register( 0xff19, (data>>8) | initflag );
|
||||
papu->write_register( 0xff1d, data & 0xff );
|
||||
papu->write_register( 0xff1e, (data>>8) | initflag );
|
||||
papu->write_register( 0, 0xff18, data & 0xff );
|
||||
papu->write_register( 0, 0xff19, (data>>8) | initflag );
|
||||
papu->write_register( 0, 0xff1d, data & 0xff );
|
||||
papu->write_register( 0, 0xff1e, (data>>8) | initflag );
|
||||
}
|
||||
|
||||
if( tfp == 0 )
|
||||
@@ -379,7 +379,7 @@ void papuInstrument::playNote( NotePlayHandle * _n,
|
||||
data += m_ch4ShiftRegWidthModel.value();
|
||||
data = data << 3;
|
||||
data += ropt;
|
||||
papu->write_register( 0xff22, data );
|
||||
papu->write_register( 0, 0xff22, data );
|
||||
}
|
||||
|
||||
int const buf_size = 2048;
|
||||
@@ -391,7 +391,7 @@ void papuInstrument::playNote( NotePlayHandle * _n,
|
||||
int avail = papu->samples_avail();
|
||||
if( avail <= 0 )
|
||||
{
|
||||
papu->end_frame();
|
||||
papu->end_frame(0);
|
||||
avail = papu->samples_avail();
|
||||
}
|
||||
datalen = framesleft>avail?avail:framesleft;
|
||||
@@ -416,7 +416,7 @@ void papuInstrument::playNote( NotePlayHandle * _n,
|
||||
|
||||
void papuInstrument::deleteNotePluginData( NotePlayHandle * _n )
|
||||
{
|
||||
delete static_cast<Basic_Gb_Apu *>( _n->m_pluginData );
|
||||
delete static_cast<Gb_Apu_Buffer *>( _n->m_pluginData );
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user