123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- /* -*- mode: c; tab-width: 4; c-basic-offset: 4; c-file-style: "linux" -*- */
- //
- // Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
- // All rights reserved.
- // Created by Lou Yihua <louyihua@21cn.com>, 2015-08-03.
- //
- // This file is part of SDLPAL.
- //
- // SDLPAL 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 3 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. If not, see <http://www.gnu.org/licenses/>.
- //
- #include "dbemuopl.h"
- #include <stdlib.h>
- bool CDBemuopl::_inited = DBOPL::InitTables();
- static inline int16_t conver_to_int16(int32_t sample)
- {
- if (sample > 32767)
- return 32767;
- else if (sample < -32768)
- return -32768;
- else
- return (int16_t)sample;
- }
- static inline uint8_t conver_to_uint8(int32_t sample)
- {
- if (sample > 32767)
- return 0xff;
- else if (sample < -32768)
- return 0;
- else
- return (uint8_t)(sample >> 8) ^ 0x80;
- }
- CDBemuopl::CDBemuopl(int rate, bool bit16, bool usestereo)
- : use16bit(bit16), stereo(usestereo), rate(rate)
- , maxlen(0), buffer(NULL)
- {
- currType = TYPE_OPL2;
- chip.Setup(rate);
- }
- CDBemuopl::~CDBemuopl()
- {
- if (buffer) delete[] buffer;
- }
- void CDBemuopl::init()
- {
- chip.Setup(rate);
- }
- void CDBemuopl::update(short *buf, int samples)
- {
- if (chip.opl3Active)
- update_opl3(buf, samples);
- else
- update_opl2(buf, samples);
- }
- void CDBemuopl::write(int reg, int val)
- {
- chip.WriteReg(reg, (Bit8u)val);
- }
- // OPL3 generate stereo samples
- void CDBemuopl::update_opl3(short *buf, int samples)
- {
- if (maxlen < samples * 2)
- {
- if (buffer) delete[] buffer;
- buffer = new int32_t[maxlen = samples * 2];
- }
- chip.GenerateBlock3(samples, buffer);
- if (use16bit)
- {
- if (stereo)
- {
- for (int i = 0; i < samples * 2; i++)
- buf[i] = conver_to_int16(buffer[i]);
- }
- else
- {
- for (int i = 0; i < samples; i++)
- buf[i] = conver_to_int16((buffer[i * 2] + buffer[i * 2 + 1]) >> 1);
- }
- }
- else
- {
- uint8_t* outbuf = (uint8_t*)buf;
- if (stereo)
- {
- for (int i = 0; i < samples * 2; i++)
- outbuf[i] = conver_to_uint8(buffer[i]);
- }
- else
- {
- for (int i = 0; i < samples; i++)
- outbuf[i] = conver_to_uint8((buffer[i * 2] + buffer[i * 2 + 1]) >> 1);
- }
- }
- }
- // OPL2 generate mono samples
- void CDBemuopl::update_opl2(short *buf, int samples)
- {
- if (maxlen < samples)
- {
- if (buffer) delete[] buffer;
- buffer = new int32_t[maxlen = samples];
- }
- chip.GenerateBlock2(samples, buffer);
- if (use16bit)
- {
- if (stereo)
- {
- for (int i = 0; i < samples; i++)
- buf[i * 2 + 1] = buf[i * 2] = conver_to_int16(buffer[i]);
- }
- else
- {
- for (int i = 0; i < samples; i++)
- buf[i] = conver_to_int16(buffer[i]);
- }
- }
- else
- {
- uint8_t* outbuf = (uint8_t*)buf;
- if (stereo)
- {
- for (int i = 0; i < samples; i++)
- outbuf[i * 2 + 1] = outbuf[i * 2] = conver_to_uint8(buffer[i]);
- }
- else
- {
- for (int i = 0; i < samples; i++)
- outbuf[i] = conver_to_uint8(buffer[i]);
- }
- }
- }
|