⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 squarewavegenerator.java

📁 一个用java写成的gb模拟器的源代码。
💻 JAVA
字号:
/*

JavaBoy
                                  
COPYRIGHT (C) 2001 Neil Millstone and The Victoria University of Manchester
                                                                         ;;;
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; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA.

*/

/** This class can mix a square wave signal with a sound buffer.
 *  It supports all features of the Gameboys sound channels 1 and 2.
 */
class SquareWaveGenerator {
	/** Sound is to be played on the left channel of a stereo sound */
	public static final int CHAN_LEFT = 1;

	/** Sound is to be played on the right channel of a stereo sound */
	public static final int CHAN_RIGHT = 2;

	/** Sound is to be played back in mono */
	public static final int CHAN_MONO = 4;

	/** Length of the sound (in frames) */
	int totalLength;

	/** Current position in the waveform (in samples) */
	int cyclePos;

	/** Length of the waveform (in samples) */
	int cycleLength;

	/** Amplitude of the waveform */
	int amplitude;

	/** Amount of time the sample stays high in a single waveform (in eighths) */
	int dutyCycle;

	/** The channel that the sound is to be played back on */
	int channel;

	/** Sample rate of the sound buffer */
	int sampleRate;

	/** Initial amplitude */
	int initialEnvelope;

	/** Number of envelope steps */
	int numStepsEnvelope;

	/** If true, envelope will increase amplitude of sound, false indicates decrease */
	boolean increaseEnvelope;

	/** Current position in the envelope */
	int counterEnvelope;

	/** Frequency of the sound in internal GB format */
	int gbFrequency;

	/** Amount of time between sweep steps. */
	int timeSweep;

	/** Number of sweep steps */
	int numSweep;

	/** If true, sweep will decrease the sound frequency, otherwise, it will increase */
	boolean decreaseSweep;

	/** Current position in the sweep */
	int counterSweep;

	/** Create a square wave generator with the supplied parameters */
	public SquareWaveGenerator(
		int waveLength,
		int ampl,
		int duty,
		int chan,
		int rate) {
		cycleLength = waveLength;
		amplitude = ampl;
		cyclePos = 0;
		dutyCycle = duty;
		channel = chan;
		sampleRate = rate;
	}

	/** Create a square wave generator at the specified sample rate */
	public SquareWaveGenerator(int rate) {
		dutyCycle = 4;
		cyclePos = 0;
		channel = CHAN_LEFT | CHAN_RIGHT;
		cycleLength = 2;
		totalLength = 0;
		sampleRate = rate;
		amplitude = 32;
		counterSweep = 0;
	}

	/** Set the sound buffer sample rate */
	public void setSampleRate(int sr) {
		sampleRate = sr;
	}

	/** Set the duty cycle */
	public void setDutyCycle(int duty) {
		switch (duty) {
			case 0 :
				dutyCycle = 1;
				break;
			case 1 :
				dutyCycle = 2;
				break;
			case 2 :
				dutyCycle = 4;
				break;
			case 3 :
				dutyCycle = 6;
				break;
		}
		//  System.out.println(dutyCycle);
	}

	/** Set the sound frequency, in internal GB format */
	public void setFrequency(int gbFrequency) {
		try {
			float frequency = 131072 / 2048;

			if (gbFrequency != 2048) {
				frequency = ((float) 131072 / (float) (2048 - gbFrequency));
			}
			//  System.out.println("gbFrequency: " + gbFrequency + "");
			this.gbFrequency = gbFrequency;
			if (frequency != 0) {
				cycleLength = (256 * sampleRate) / (int) frequency;
			} else {
				cycleLength = 65535;
			}
			if (cycleLength == 0)
				cycleLength = 1;
			//  System.out.println("Cycle length : " + cycleLength + " samples");
		} catch (ArithmeticException e) {
			// Skip ip
		}
	}

	/** Set the channel for playback */
	public void setChannel(int chan) {
		channel = chan;
	}

	/** Set the envelope parameters */
	public void setEnvelope(int initialValue, int numSteps, boolean increase) {
		initialEnvelope = initialValue;
		numStepsEnvelope = numSteps;
		increaseEnvelope = increase;
		amplitude = initialValue * 2;
	}

	/** Set the frequency sweep parameters */
	public void setSweep(int time, int num, boolean decrease) {
		timeSweep = (time + 1) / 2;
		numSweep = num;
		decreaseSweep = decrease;
		counterSweep = 0;
		//  System.out.println("Sweep: " + time + ", " + num + ", " + decrease);
	}

	public int getLength() {
		return totalLength;
	}
	
	public void setLength(int gbLength) {
		if (gbLength == -1) {
			totalLength = -1;
		} else {
			totalLength = (64 - gbLength) / 4;
		}
	}

	public void setLength3(int gbLength) {
		if (gbLength == -1) {
			totalLength = -1;
		} else {
			totalLength = (256 - gbLength) / 4;
		}
	}

	public void setVolume3(int volume) {
		switch (volume) {
			case 0 :
				amplitude = 0;
				break;
			case 1 :
				amplitude = 32;
				break;
			case 2 :
				amplitude = 16;
				break;
			case 3 :
				amplitude = 8;
				break;
		}
		//  System.out.println("A:"+volume);
	}

	/** Output a frame of sound data into the buffer using the supplied frame length and array offset. */
	public void play(byte[] b, int length, int offset) {
		int val = 0;

		if (totalLength != 0) {
			totalLength--;

			if (timeSweep != 0) {
				counterSweep++;
				if (counterSweep > timeSweep) {
					if (decreaseSweep) {
						setFrequency(gbFrequency - (gbFrequency >> numSweep));
					} else {
						setFrequency(gbFrequency + (gbFrequency >> numSweep));
					}
					counterSweep = 0;
				}
			}

			counterEnvelope++;
			if (numStepsEnvelope != 0) {
				if (((counterEnvelope % numStepsEnvelope) == 0)
					&& (amplitude > 0)) {
					if (!increaseEnvelope) {
						if (amplitude > 0)
							amplitude -= 2;
					} else {
						if (amplitude < 16)
							amplitude += 2;
					}
				}
			}
			for (int r = offset; r < offset + length; r++) {

				if (cycleLength != 0) {
					if (((8 * cyclePos) / cycleLength) >= dutyCycle) {
						val = amplitude;
					} else {
						val = -amplitude;
					}
				}

				/*    if (cyclePos >= (cycleLength / 2)) {
				     val = amplitude;
				    } else {
				     val = -amplitude;
				    }*/

				if ((channel & CHAN_LEFT) != 0)
					b[r * 2] += val;
				if ((channel & CHAN_RIGHT) != 0)
					b[r * 2 + 1] += val;
				if ((channel & CHAN_MONO) != 0)
					b[r] += val;

				//   System.out.print(val + " ");

				cyclePos = (cyclePos + 256) % cycleLength;
			}
		}
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -