我正在开发一个通过单击键盘键来播放声音的程序。我已经开始使用它了,但是当我尝试可视化该声音时,声音停止播放。因此,我既可以播放声音,也可以发出波浪,但不能同时演奏。如何使它们都起作用?
public class GuitarHeroVisualizer {
public static void main(String[] args) {
String keyboard = "q2we4r5ty7u8i9op-[=zxdcfvgbnjmk,.;/' ";
GuitarString[] strings = new GuitarString[37];
int x = 0;
for (int i = 0; i < 37; i++) {
strings[i] = new GuitarString(440.0 * Math.pow(1.05956, i - 23));
}
while (true) {
if (StdDraw.hasNextKeyTyped()) {
char key = StdDraw.nextKeyTyped();
int j = keyboard.indexOf(key);
if (j != -1) {
strings[j].pluck();
}
}
// compute the superposition of samples
//double sample = stringA.sample() + stringC.sample();
double sample = 0;
for (int i = 0; i < 37; i++) {
sample += strings[i].sample();
}
// play the sample on standard audio
if(sample != 0)
{
StdDraw.setXscale(0, 90);
StdDraw.line(x, 0, x + 1, sample);
StdDraw.line(x + 1, sample, x + 2, 0);
x += 2;
}
StdAudio.play(sample);
for (int i = 0; i < 37; i++) {
strings[i].tic();
}
}
}
}
其他两个班级:
public class GuitarString {
RingBuffer buffer;
int N;
int time = 0;
public GuitarString(double frequency) {
N = (int)(44100/frequency);
buffer = new RingBuffer(N);
for (int i = 0; i < N; i++) {
buffer.enqueue(0);
}
}
public GuitarString(double[] init) {
buffer = new RingBuffer(init.length + 1);
N = init.length + 1;
for (int i = 0; i < init.length; i++) {
buffer.enqueue(init[i]);
}
}
public void pluck() {
for (int i = 0; i < N; i++) {
buffer.dequeue();
}
for (int i = 0; i < N; i++) {
buffer.enqueue(Math.random()-0.5);
}
}
public void tic() {
time++;
double first = buffer.dequeue();
double avg = (buffer.peek() + first) / 2;
buffer.enqueue(avg * .994);
}
public double sample() {
return buffer.peek();
}
public int time() {
return time;
}
}
下一个:
public class RingBuffer {
double[] nums;
int capacity;
int size = 0;
int first = 0;
int last = 0;
public RingBuffer(int cap) {
capacity = cap;
nums = new double[cap];
}
public int size() {
return size;
}
public boolean isEmpty() {
if (size() == 0) {
return true;
}
return false;
}
public boolean isFull() {
if (size() == capacity) {
return true;
}
return false;
}
public void enqueue(double x) {
if (isFull()) {
throw new RuntimeException("Queue is full.");
}
nums[last] = x;
last++;
if(last == capacity) {last = 0;}
size++;
}
public double dequeue() {
if (isEmpty()) {
throw new RuntimeException("Queue is empty.");
}
double num = nums[first];
first++;
if(first == capacity) {first = 0;}
size--;
return num;
}
public double peek() {
return nums[first];
}
}
这是std类: https://introcs.cs.princeton.edu/java/stdlib/javadoc/StdDraw.html https://introcs.cs.princeton.edu/java/stdlib/javadoc/StdAudio.html