diff --git a/plugins/papu/Basic_Gb_Apu.cpp b/plugins/papu/Basic_Gb_Apu.cpp deleted file mode 100644 index 53c2fab17..000000000 --- a/plugins/papu/Basic_Gb_Apu.cpp +++ /dev/null @@ -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 ); -} - -// <--- diff --git a/plugins/papu/Basic_Gb_Apu.h b/plugins/papu/Basic_Gb_Apu.h deleted file mode 100644 index 0175fbf38..000000000 --- a/plugins/papu/Basic_Gb_Apu.h +++ /dev/null @@ -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 - diff --git a/plugins/papu/CMakeLists.txt b/plugins/papu/CMakeLists.txt index 4c5ddd920..443dd5e37 100644 --- a/plugins/papu/CMakeLists.txt +++ b/plugins/papu/CMakeLists.txt @@ -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 diff --git a/plugins/papu/Gb_Apu_Buffer.cpp b/plugins/papu/Gb_Apu_Buffer.cpp new file mode 100644 index 000000000..1a817eb2a --- /dev/null +++ b/plugins/papu/Gb_Apu_Buffer.cpp @@ -0,0 +1,66 @@ +/* + * Gb_Apu_Buffer.cpp - Gb_Apu subclass which allows direct buffer access + * Copyright (c) 2017 Tres Finocchiaro + * + * 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); +} + diff --git a/plugins/papu/Gb_Apu_Buffer.h b/plugins/papu/Gb_Apu_Buffer.h new file mode 100644 index 000000000..065fbe82d --- /dev/null +++ b/plugins/papu/Gb_Apu_Buffer.h @@ -0,0 +1,54 @@ +/* + * Gb_Apu_Buffer.cpp - Gb_Apu subclass which allows direct buffer access + * Copyright (c) 2017 Tres Finocchiaro + * + * 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 + diff --git a/plugins/papu/papu_instrument.cpp b/plugins/papu/papu_instrument.cpp index 3d4dfcf5d..d08592af1 100644 --- a/plugins/papu/papu_instrument.cpp +++ b/plugins/papu/papu_instrument.cpp @@ -27,9 +27,9 @@ #include #include -#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( _n->m_pluginData ); + Gb_Apu_Buffer *papu = static_cast( _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( _n->m_pluginData ); + delete static_cast( _n->m_pluginData ); }