From c903e6df7b3dde7de714311360130a3d0219d873 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Sun, 24 Feb 2019 00:13:35 +0100 Subject: javaopl3 work in progress --- src/chips/java_opl3.cpp | 94 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/chips/java_opl3.cpp (limited to 'src/chips/java_opl3.cpp') diff --git a/src/chips/java_opl3.cpp b/src/chips/java_opl3.cpp new file mode 100644 index 0000000..ebf7899 --- /dev/null +++ b/src/chips/java_opl3.cpp @@ -0,0 +1,94 @@ +/* + * Interfaces over Yamaha OPL3 (YMF262) chip emulators + * + * Copyright (c) 2017-2019 Vitaly Novichkov (Wohlstand) + * + * This library 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 library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "java_opl3.h" +#include "java/OPL3.cpp" + +JavaOPL3::JavaOPL3() : + OPLChipBaseBufferedT(), + m_chip(new JavaOPL::OPL3(true)) +{ + reset(); +} + +JavaOPL3::~JavaOPL3() +{ + JavaOPL::OPL3 *chip_r = reinterpret_cast(m_chip); + delete chip_r; +} + +void JavaOPL3::setRate(uint32_t rate) +{ + OPLChipBaseBufferedT::setRate(rate); + JavaOPL::OPL3 *chip_r = reinterpret_cast(m_chip); + chip_r->Reset(); +} + +void JavaOPL3::reset() +{ + OPLChipBaseBufferedT::reset(); + JavaOPL::OPL3 *chip_r = reinterpret_cast(m_chip); + chip_r->Reset(); +} + +void JavaOPL3::writeReg(uint16_t addr, uint8_t data) +{ + JavaOPL::OPL3 *chip_r = reinterpret_cast(m_chip); + chip_r->WriteReg(addr, data); +} + +void JavaOPL3::writePan(uint16_t addr, uint8_t data) +{ + JavaOPL::OPL3 *chip_r = reinterpret_cast(m_chip); + // TODO panning +} + +void JavaOPL3::nativeGenerateN(int16_t *output, size_t frames) +{ + JavaOPL::OPL3 *chip_r = reinterpret_cast(m_chip); + + enum { maxframes = 256 }; + + float buf[2 * maxframes]; + while(frames > 0) + { + memset(buf, 0, sizeof(buf)); + + size_t curframes = (frames < maxframes) ? frames : maxframes; + chip_r->Update(buf, curframes); + + size_t cursamples = 2 * curframes; + for(size_t i = 0; i < cursamples; ++i) + { + int32_t sample = (int32_t)lround(32768 * buf[i]); + sample = (sample > -32768) ? sample : -32768; + sample = (sample < +32767) ? sample : +32767; + output[i] = (int16_t)sample; + } + + output += cursamples; + frames -= curframes; + } +} + +const char *JavaOPL3::emulatorName() +{ + return "Java 1.0.6 OPL3"; +} -- cgit v1.2.3 From e587395a064d19f894c5295e1d97af4d2fb87ea7 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Sun, 24 Feb 2019 00:41:22 +0100 Subject: java: output volume and panning --- src/chips/java_opl3.cpp | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'src/chips/java_opl3.cpp') diff --git a/src/chips/java_opl3.cpp b/src/chips/java_opl3.cpp index ebf7899..d35c023 100644 --- a/src/chips/java_opl3.cpp +++ b/src/chips/java_opl3.cpp @@ -19,7 +19,14 @@ */ #include "java_opl3.h" -#include "java/OPL3.cpp" +#include "java/JavaOPL3.hpp" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif +#ifndef M_SQRT1_2 +# define M_SQRT1_2 0.70710678118654752440 +#endif JavaOPL3::JavaOPL3() : OPLChipBaseBufferedT(), @@ -39,6 +46,10 @@ void JavaOPL3::setRate(uint32_t rate) OPLChipBaseBufferedT::setRate(rate); JavaOPL::OPL3 *chip_r = reinterpret_cast(m_chip); chip_r->Reset(); + + float pan = sinf(M_SQRT1_2); + for (unsigned channel = 0; channel < 18; ++channel) + chip_r->SetPanning(channel, pan, pan); } void JavaOPL3::reset() @@ -57,7 +68,14 @@ void JavaOPL3::writeReg(uint16_t addr, uint8_t data) void JavaOPL3::writePan(uint16_t addr, uint8_t data) { JavaOPL::OPL3 *chip_r = reinterpret_cast(m_chip); - // TODO panning + + unsigned high = (addr >> 8) & 0x01; + unsigned regm = addr & 0xff; + unsigned channel = 9 * high + (regm & 0x0f); + + float phase = (data == 63 || data == 64) ? 63.5f : (float)data; + phase *= (float)(M_PI / 2 / 127); + chip_r->SetPanning(channel, sinf(phase), cosf(phase)); } void JavaOPL3::nativeGenerateN(int16_t *output, size_t frames) @@ -77,7 +95,7 @@ void JavaOPL3::nativeGenerateN(int16_t *output, size_t frames) size_t cursamples = 2 * curframes; for(size_t i = 0; i < cursamples; ++i) { - int32_t sample = (int32_t)lround(32768 * buf[i]); + int32_t sample = (int32_t)lround(4096 * buf[i]); sample = (sample > -32768) ? sample : -32768; sample = (sample < +32767) ? sample : +32767; output[i] = (int16_t)sample; -- cgit v1.2.3 From fdf213207e6793851dd8088d597685045c5961b7 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Sun, 24 Feb 2019 00:53:57 +0100 Subject: fix some warnings --- src/chips/java_opl3.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/chips/java_opl3.cpp') diff --git a/src/chips/java_opl3.cpp b/src/chips/java_opl3.cpp index d35c023..39477e2 100644 --- a/src/chips/java_opl3.cpp +++ b/src/chips/java_opl3.cpp @@ -25,7 +25,7 @@ #define M_PI 3.14159265358979323846 #endif #ifndef M_SQRT1_2 -# define M_SQRT1_2 0.70710678118654752440 +#define M_SQRT1_2 0.70710678118654752440 #endif JavaOPL3::JavaOPL3() : @@ -47,7 +47,7 @@ void JavaOPL3::setRate(uint32_t rate) JavaOPL::OPL3 *chip_r = reinterpret_cast(m_chip); chip_r->Reset(); - float pan = sinf(M_SQRT1_2); + float pan = sinf((float)M_SQRT1_2); for (unsigned channel = 0; channel < 18; ++channel) chip_r->SetPanning(channel, pan, pan); } @@ -89,8 +89,8 @@ void JavaOPL3::nativeGenerateN(int16_t *output, size_t frames) { memset(buf, 0, sizeof(buf)); - size_t curframes = (frames < maxframes) ? frames : maxframes; - chip_r->Update(buf, curframes); + size_t curframes = (frames < (size_t)maxframes) ? frames : (size_t)maxframes; + chip_r->Update(buf, (int)curframes); size_t cursamples = 2 * curframes; for(size_t i = 0; i < cursamples; ++i) -- cgit v1.2.3