- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是我第一次尝试编写除了书中练习之外的程序。当我完成后,它将成为一个钢琴卷帘编辑器 MIDI 音序器。用户输入一组歌词。该程序将单词转换为钢琴卷帘编辑器上的音符,然后用户可以四处移动并构建旋律。我有用于提交歌词的 GUI 和一个基本的钢琴卷帘面板。我的面板上出现了音符,上面印有歌词。现在我正处于尝试构建一个可以播放这些音符的音序器/合成器的阶段。目前的复杂性有点难以承受,所以我正在尝试逐步解决这个问题。我学习了《Head First Java》一书中的音乐节拍盒,以及《Killer Game Programming》一书中的 MIDI 章节。我已经一遍又一遍地研究 JavaSound 上的 Java API。考虑到所有这些,我构建了一个包含音序器和合成器的类,并且我尝试简单地创建一系列音符并播放它们(甚至不用担心将它们连接到屏幕上的图形音符形状)。但还没有播放任何内容。我现在有四个类(一类用于 GUI,一类用于钢琴卷帘面板,一类用于图形音符对象,一类用于音乐引擎)。我将尝试在下面发布一些代码。如果有人可以帮助我找出为什么没有播放,我将不胜感激。
这是音乐引擎类。希望我在这里正确发布代码:
import javax.sound.midi.*;
public class MusicEngine {
private Sequencer sequencer;
private Sequence sequence;
private Synthesizer synthesizer;
private Track track;
MidiEvent event;
// Constructor
public MusicEngine() {
createMidi();
}
// Get sequencer and sequence and track
public void createMidi() {
try {
sequencer = MidiSystem.getSequencer();
if (sequencer == null) {
System.out.println("Cannot get a sequencer");
System.exit(0);
}
sequencer.open();
// If sequencer is not the same as synthesizer, link the two
// (required in J2SE 5.0)
if (!(sequencer instanceof Synthesizer)) {
System.out.println("Linking the sequencer to the synthesizer");
synthesizer = MidiSystem.getSynthesizer();
synthesizer.open();
Receiver synthReceiver = synthesizer.getReceiver();
Transmitter seqTransmitter = sequencer.getTransmitter();
seqTransmitter.setReceiver(synthReceiver);
} else
synthesizer = (Synthesizer)sequencer;
sequence = new Sequence(Sequence.PPQ, 4);
track = sequence.createTrack();
sequencer.setTempoInBPM(120);
} catch(MidiUnavailableException e) {
System.out.println("No sequencer available");
System.exit(0);
} catch(Exception e) {
e.printStackTrace();
System.exit(0);
}
}
// Create an individual MIDI event
public MidiEvent createEvent(int command, int channel, int one, int two, int tick) {
event = null;
try {
ShortMessage a = new ShortMessage();
a.setMessage(command, channel, one, two);
event = new MidiEvent(a, tick);
} catch(InvalidMidiDataException e) {
e.printStackTrace();
}
return event;
}
public void add(MidiEvent event) {
track.add(event);
}
public void playSong(int tempo) {
try {
sequencer.setSequence(sequence);
}
catch (InvalidMidiDataException e) {
e.printStackTrace();
}
sequencer.start();
}
}
这是尝试演奏一些音符的钢琴卷帘面板:
import javax.sound.midi.ShortMessage;
import javax.swing.*;
import javax.swing.event.MouseInputAdapter;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
public class MelodyPanel extends JPanel {
private String[] lyricList;
private ArrayList<MovableNote> noteList = new ArrayList<>();
private int xCoord = 1;
private int yCoord = 50;
private int startX, startY, stopX, stopY, diffX, diffY;
private int lyricPosition;
private int noteWidth = 40;
private static final int DEFAULT_NOTE_HEIGHT = 15;
private static final int SIXTEENTH_BEAT_WIDTH = 50;
private MusicEngine musicEngine;
private String[] noteNames = {"C1","C#1/Db1","D1","D#1/Eb1","E1","F1","F#1/Gb1","G1","G#/Ab1","A1","A#1/Bb1","B1",
"C2","C#2/Db2","D2","D#2/Eb2","E2","F2","F#2/Gb2","G2","G#2/Ab2","A2","A#2/Bb2","B2",
"C3","C#3/Db3","D3","D#3/Eb3","E3","F3","F#3/Gb3","G3","G#3/Ab3","A3","A#3/Bb3","B3",
"C4","C#4/Db4","D4","D#4/Eb4","E4","F4","F#4/Gb4","G4","G#4/Ab4","A4","A#4/Bb4","B4",
"C5","C#5/Db5","D5","D#5/Eb5","E5","F5","F#5/Gb5","G5","G#5/Ab5","A5","A#5/Bb5","B5",
"C6","C#6/Db6","D6","D#6/Eb6","E6","F6","F#6/Gb6","G6","G#6/Ab6","A6","A#6/Bb6","B6",
"C7","C#7/Db7","D7","D#7/Eb7","E7","F7","F#7/Gb7","G7","G#7/Ab7","A7","A#7/Bb7","B7"};
// Measure length = default note length x number of beats
private static final int FOUR_FOUR_MEASURE_LENGTH = SIXTEENTH_BEAT_WIDTH * 16;
private static final int THREE_FOUR_MEASURE_LENGTH = SIXTEENTH_BEAT_WIDTH * 12;
private static final int SIX_EIGHT_MEASURE_LENGTH = SIXTEENTH_BEAT_WIDTH * 24;
private Font f = new Font("SansSerif", Font.BOLD, 14);
private MovableNote mNote;
private MovableNote selectedNote = null;
private boolean dragging = false;
// Create an INITIAL MelodyPanel with lyrics, RESET to flatline melody
public void showMelodyPanel(String[] lyricList) {
setBackground(Color.BLACK);
this.lyricList = lyricList;
// Create the MusicEngine sequencer and synth
musicEngine = new MusicEngine();
// For every syllable in the lyricList, create a MovableNote and put it in the ArrayList
for (int i = 0; i < lyricList.length; i++) {
lyricPosition = i;
mNote = new MovableNote((SIXTEENTH_BEAT_WIDTH * lyricPosition) + 2, DEFAULT_NOTE_HEIGHT * 10, noteWidth, DEFAULT_NOTE_HEIGHT, lyricList[i]);
noteList.add(mNote);
// try adding a musical note to the track
musicEngine.add(musicEngine.createEvent(ShortMessage.NOTE_ON, 0, 60, 100, i * 16));
musicEngine.add(musicEngine.createEvent(ShortMessage.NOTE_OFF, 0, 60, 100, i * 16 + 4));
}
// try to play the song
musicEngine.playSong(120);
// The panel responds when you click on it
addMouseListener(new NoteListener());
// The panel responds when you drag the mouse on it
addMouseMotionListener(new NoteListener());
}
@Override /** Paint the melodyPanel */
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Draw the note rows, iterating backwards through the noteNames array
int counter1 = 1;
int counter2 = 6;
NoteRow row;
for (int i = 83; i >= 0; i--) {
row = new NoteRow(0, i * DEFAULT_NOTE_HEIGHT, SIXTEENTH_BEAT_WIDTH * 16 * lyricList.length, DEFAULT_NOTE_HEIGHT, noteNames[i]);
row.draw(g);
// Place horizontal lines to separate rows representing adjacent white piano keys
if (counter1 % 12 == 0 || counter2 % 12 == 0)
g.setColor(Color.DARK_GRAY);
g.drawLine(0, i * DEFAULT_NOTE_HEIGHT, this.getWidth(), i * DEFAULT_NOTE_HEIGHT);
counter1++;
counter2++;
}
// Draw the sixteenth note lines
for (int i = 0; i < this.getWidth(); i += FOUR_FOUR_MEASURE_LENGTH / 16) {
g.setColor(new Color(112,128,144));
g.drawLine(i, 0, i, this.getHeight());
}
// Draw the eighth note lines
for (int i = 0; i < this.getWidth(); i += FOUR_FOUR_MEASURE_LENGTH / 8) {
g.setColor(new Color(95,158,160));
g.drawLine(i, 0, i, this.getHeight());
}
// Draw the quarter note lines
for (int i = 0; i < this.getWidth(); i += FOUR_FOUR_MEASURE_LENGTH / 4) {
g.setColor(new Color(70,130,180));
g.drawLine(i, 0, i, this.getHeight());
}
// Draw the measure lines
for (int i = 0; i < this.getWidth(); i += FOUR_FOUR_MEASURE_LENGTH) {
g.setColor(Color.WHITE);
g.drawLine(i, 0, i, this.getHeight());
}
// For every MovableNote in the ArrayList draw a note on the MelodyPanel
for (int i = 0; i < noteList.size(); i++) {
if (noteList != null) {
noteList.get(i).draw(g);
// Paint the current syllable or word onto the current note
g.setColor(Color.BLACK);
g.setFont(f);
g.drawString(noteList.get(i).getSyllable(), (int)noteList.get(i).getX() + 2, (int)noteList.get(i).getY() + 13);
} else {
// Code that informs user they need to submit some lyrics
// Or something else if the user wishes to not use lyrics
}
}
}
private class NoteListener extends MouseInputAdapter {
@Override
public void mousePressed(MouseEvent e) {
startX = e.getX();
startY = e.getY();
dragging = true;
for (MovableNote n: noteList) {
if (n.isHit(startX, startY)) {
if (selectedNote != null) {
selectedNote = n;
System.out.println("You have selected a note");
selectedNote.setNoteColor(Color.BLACK);
repaint();
} else {
selectedNote.setNoteColor(Color.YELLOW);
repaint();
selectedNote = null;
}
}
}
testPress(e.getX(), e.getY());
}
@Override public void mouseReleased(MouseEvent e) {
dragging = false;
}
@Override
public void mouseDragged(MouseEvent e) {
stopX = e.getX();
stopY = e.getY();
for (MovableNote n: noteList) {
if (n.isHit(e.getX(), e.getY())) {
System.out.println("You tried to drag a note");
diffX = stopX - startX;
diffY = stopY - startY;
n.translate(diffX, diffY);
repaint();
}
}
// code to reset the the old x, y values
startX += diffX;
startY += diffY;
testDrag(e.getX(), e.getY());
}
}
// When mouse is pressed on panel, a note is created without any connection to a lyric
private void testPress(int x, int y) {
// Test to see if mouse listener works
System.out.println("The mouse was clicked on coordinates " + x + ", " + y);
}
// When mouse drags a note, the note moves
private void testDrag(int x, int y) {
// Test to see if mouse listener works
System.out.println("The mouse dragged to this location: " + x + ", " + y);
}
// Individual row that represents a single pitch horizontally
private class NoteRow extends Rectangle {
Color color = (Color.GRAY);
private String pitch;
// Constructor
public NoteRow(int x, int y, int width, int height, String pitch) {
super(x, y, width, height);
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.pitch = pitch;
// Set color of the row according to if it's a black keyboard key or a white keyboard key
if (pitch.startsWith("C#") || pitch.startsWith("Db") || pitch.startsWith("D#") ||
pitch.startsWith("Eb") || pitch.startsWith("F#") || pitch.startsWith("Gb") || pitch.startsWith("G#") ||
pitch.startsWith("Ab") || pitch.startsWith("A#") || pitch.startsWith("Bb")) {
this.color = (Color.DARK_GRAY);
} else {
this.color = (Color.LIGHT_GRAY);
}
}
// Method for the note to draw itself
void draw(Graphics gr) {
Graphics2D g = (Graphics2D)gr;
g.setColor(color);
g.fill(this);
}
}
}
最佳答案
您似乎忘记将您创建的 MidiEvent 添加到轨道中。我找不到任何调用 Track.add(MidiEvent) 的地方。可能您的序列是空的。
关于java - 让音序器在 JavaSound (Java SE7) 中播放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12652940/
我无法从远程 Ubuntu 服务器打开在本地 macOS 机器上运行的 Stata 的 GUI。 我已经安装了stata-se在我的本地机器上,我可以打开 X11 应用程序,如 xclock和 xey
我正在尝试将 tobit 模型从 Stata 迁移到 R。 稳健的 Stata 命令只需将 ,vce(robust) 添加到模型中。对于集群,它将是 ,vce(cluster idvar)。 可重现的
以下代码在 JavaSE 6 中工作正常,但在 JavaSE 7 中执行时抛出 ConnectException(超时)。这是 JDK7 错误还是错误代码?实在是看不懂…… public sta
在 SE 6 或 SE 7 的任何类中是否有任何地方不是最终的,即可以直接设置的字段? 我正在研究从另一种语言 (Haskell) 到 Java 的绑定(bind),我正在寻找那个特定的案例来检查我的
我想学习 Java,特别是 Android 开发,因为我要买一台新的平板电脑,但也想学习 Java 可以做的许多其他事情(Struts、网络开发、JWebSockets 等)。我是一位在 PHP、Ja
我正在尝试使用 websockets 编写一些东西,但遇到了无法解析的导入问题。 经过几次尝试,我创建了两个相同的项目。一份使用 Java SE9,一份使用 JAVA SE-1.8。 导入适用于 1.
我使用 Weld SE 创建了一个简单的 JavaSE 应用程序。我正在尝试使用 gradle run 运行它会抛出异常: :compileJava UP-TO-DATE :processResour
我正在尝试将现有应用程序的 Java JDK 版本从 Java 5 更改为 Java 6(更新 38)。该应用程序使用一些 JAXB 生成的类来编码/解码我们从远程服务器发送/接收的 XML。 XML
我有一个命令行 Java 应用程序,它在 Windows 7 x64 平台上读写文件。当前应用程序使用随附的 IBM Java SE 6 运行。结构如下: APP_ROOT some_fold
在主题中,我有一个使用 Java 1.6 编译的 Java SE 应用程序部署在 Java 1.7 运行时环境中。由于 Java 是高度向后兼容的,我假设一切都会很好 - 但自从它部署在 1.7 环境
我正在开发一个 JavaFX 2 项目,并且该应用程序必须使用另一个 main 方法(根据生成的 JAR list 为 com.javafx.main.Main)启动。据官方焊缝reference引导
内部类 1. 内部类的概述 内部类指的是****把类定义在另一个类的内部,该类就被称为内部类。类名不需要和源文件名相同。 内部类的种类: 在Java中,内部类的使用共有两种情况: (1). 在类中定义
我正在开发一个 Java 应用程序,用于在 yfrog.com 上上传图像。 我可以在API页面成功发帖但没有二进制文件,只有一个字符串参数 . 另外我使用的方法只接受“字符串”。 URLConnec
我在我的应用程序中创建了一个与端口绑定(bind)的 ServerSocket。我将此应用程序分发到同一网络上连接的 PC。我可以使用此端口向安装了该应用程序的任何 PC 发送请求。现在接收者可以接收
我已经解决了Java SE Security特点。 据我了解,此标准功能的整体理念是保护用户免受恶意软件的侵害。 对于 Web 上的两个 Java 应用程序,默认情况下启用 SecurityManag
当我编译代码时,我的 java 应用程序出现问题,它说找不到符号 roomLength。应用程序应该做的是提示用户输入房间名称,然后如果它是“退出”,那么它必须关闭程序。否则会提示房间的长、宽、高。如
我不明白为什么下面的代码返回“false” String x="Hello World"; String z=" Hello World".trim(); System.out.println(x==
首先,我要说的是我在观看此视频时完成了所有这些操作:https://www.youtube.com/watch?v=Hl-zzrqQoSE 所以,我尝试下载适用于 Windows 64 位的 jdk-
我正在尝试创建一个具有用户友好界面的网络Java SE应用程序,我对GUI库(Swing、SWT、JavaFX)感到很困惑 以及关于应用程序 (MVC、PureMVC) 的架构 任何有经验的人都可以给
拜托,我有一个 java 桌面应用程序,我想要一种将我的桌面应用程序连接到在线数据库的方法。我想知道可用于执行此操作的技术。 最佳答案 您可以只使用 JDBC。 您必须创建与数据库属性的连接,例如:
我是一名优秀的程序员,十分优秀!