Add files via upload

This commit is contained in:
SuspiciousActivity authored and GitHub committed 2022-09-12 00:08:02 +02:00
1 parent afbe80adcf
commit 186f862656
4 files changed
+385

No files matched your search

+89
View File
@@ -0,0 +1,89 @@
package me.SoundDraw;
import java.io.IOException;
import java.io.InputStream;
import java.util.function.IntSupplier;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
public class AudioPlayer extends Thread {
private final IntToByteFunction func;
private final IntSupplier volume;
private final AudioFormat format;
private final SourceDataLine sourceDataLine;
public AudioPlayer(IntToByteFunction func, IntSupplier volume) throws LineUnavailableException {
this.func = func;
this.volume = volume;
format = new AudioFormat(Main.SAMPLE_RATE, 8, 1, true, false);
DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, format);
sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
}
@Override
public void run() {
try {
sourceDataLine.open(format);
} catch (LineUnavailableException e) {
throw new RuntimeException(e);
}
sourceDataLine.start();
try (AudioGen gen = new AudioGen()) {
byte[] data = new byte[4096];
int read = 0;
while ((read = gen.read(data)) > 0) {
sourceDataLine.write(data, 0, read);
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
sourceDataLine.drain();
sourceDataLine.close();
}
}
private class AudioGen extends InputStream {
private int index;
@Override
public int read() throws IOException {
return (int) (func.apply(index++) * volume.getAsInt() / 100);
}
@Override
public int read(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
int c = read();
b[off] = (byte) c;
int i = 1;
try {
for (; i < len; i++) {
c = read();
b[off + i] = (byte) c;
}
} catch (IOException ee) {
}
return i;
}
}
}
+151
View File
@@ -0,0 +1,151 @@
package me.SoundDraw;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ContainerAdapter;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class DrawingBoard extends JPanel {
private static final int STEP = 100;
private static final int DEFAULT_SIZE = STEP * 5;
private final MouseListener listener;
private byte[] data = new byte[DEFAULT_SIZE];
private int lastEditedSize = DEFAULT_SIZE;
private boolean down = false;
private Point lastPos;
public DrawingBoard() {
listener = new MouseListener();
setBackground(Color.black);
addMouseListener(listener);
addMouseMotionListener(listener);
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
repaint();
}
});
}
public byte getSampleAt(int idx) {
return data[idx % data.length];
}
public int resizeData(int mul) {
int size = mul * STEP;
if (data.length == size)
return -1;
int oldSize = data.length;
data = Arrays.copyOf(data, size);
if (oldSize < size) {
for (int i = lastEditedSize; i + lastEditedSize <= size; i += lastEditedSize) {
System.arraycopy(data, 0, data, i, lastEditedSize);
}
} else if (size < lastEditedSize) {
lastEditedSize = size;
}
SwingUtilities.invokeLater(this::repaint);
return size;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
g.setColor(Color.darkGray);
g.drawLine(0, height / 2, width, height / 2);
g.setColor(Color.white);
for (int i = 0; i < data.length - 1; i++) {
g.drawLine(i * width / data.length, (data[i] + 128) * height / 256, (i + 1) * width / data.length,
(data[i + 1] + 128) * height / 256);
}
}
private class MouseListener extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
down = true;
lastPos = e.getPoint();
firePaint(e.getPoint());
e.consume();
}
@Override
public void mouseReleased(MouseEvent e) {
firePaint(e.getPoint());
down = false;
lastPos = null;
e.consume();
}
@Override
public void mouseDragged(MouseEvent e) {
firePaint(e.getPoint());
e.consume();
}
private void firePaint(Point pos) {
if (!down)
return;
lastEditedSize = data.length;
int width = getWidth();
int height = getHeight();
int stepHalfX = width / data.length / 2;
int stepHalfY = height / 256 / 2;
if (pos.y < 0)
pos.y = 0;
else if (pos.y >= height)
pos.y = height - 1;
if (lastPos == null)
lastPos = pos;
try {
Point pLow = pos.x < lastPos.x ? pos : lastPos;
Point pHigh = pos.x < lastPos.x ? lastPos : pos;
int lastIdx = (pLow.x + stepHalfX) * data.length / width;
int newIdx = (pHigh.x + stepHalfX) * data.length / width;
int lastVal = pLow.y;
int newVal = pHigh.y;
int diffIdx = newIdx - lastIdx + 1;
float diff = newVal - lastVal;
for (int curIdx = lastIdx, off = 0; (curIdx = lastIdx + off) <= newIdx; off++) {
if (curIdx < 0 || curIdx >= data.length)
continue;
int val = Math.round(lastVal + diff * off / diffIdx);
data[curIdx] = (byte) (((val * 256 + stepHalfY) / height) - 128);
curIdx++;
}
repaint();
} finally {
lastPos = pos;
}
}
}
}
+6
View File
@@ -0,0 +1,6 @@
package me.SoundDraw;
@FunctionalInterface
public interface IntToByteFunction {
byte apply(int value);
}
+139
View File
@@ -0,0 +1,139 @@
package me.SoundDraw;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.util.Locale;
import javax.sound.sampled.LineUnavailableException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.JLabel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import java.awt.FlowLayout;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.Color;
import javax.swing.SpringLayout;
import javax.swing.BoxLayout;
import java.awt.Component;
import javax.swing.Box;
public class Main {
public static final int SAMPLE_RATE = 44100;
private JFrame frmAudiodraw;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main window = new Main();
window.frmAudiodraw.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*
* @throws LineUnavailableException
*/
public Main() throws LineUnavailableException {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e1) {
e1.printStackTrace();
}
initialize();
}
/**
* Initialize the contents of the frame.
*
* @throws LineUnavailableException
*/
private void initialize() throws LineUnavailableException {
frmAudiodraw = new JFrame();
frmAudiodraw.getContentPane().setBackground(Color.DARK_GRAY);
frmAudiodraw.setTitle("Sound Draw");
frmAudiodraw.setBounds((int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2 - 250),
(int) (Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2 - 150), 500, 300);
frmAudiodraw.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SpringLayout springLayout = new SpringLayout();
frmAudiodraw.getContentPane().setLayout(springLayout);
DrawingBoard board = new DrawingBoard();
springLayout.putConstraint(SpringLayout.WEST, board, 10, SpringLayout.WEST, frmAudiodraw.getContentPane());
springLayout.putConstraint(SpringLayout.SOUTH, board, -10, SpringLayout.SOUTH, frmAudiodraw.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, board, -10, SpringLayout.EAST, frmAudiodraw.getContentPane());
frmAudiodraw.getContentPane().add(board);
JPanel controls = new JPanel();
controls.setBackground(Color.DARK_GRAY);
springLayout.putConstraint(SpringLayout.NORTH, controls, 10, SpringLayout.NORTH, frmAudiodraw.getContentPane());
springLayout.putConstraint(SpringLayout.WEST, controls, 10, SpringLayout.WEST, frmAudiodraw.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, controls, -10, SpringLayout.EAST, frmAudiodraw.getContentPane());
springLayout.putConstraint(SpringLayout.NORTH, board, 10, SpringLayout.SOUTH, controls);
frmAudiodraw.getContentPane().add(controls);
JPanel panelVolume = new JPanel();
panelVolume.setBackground(Color.DARK_GRAY);
panelVolume.setLayout(new BoxLayout(panelVolume, BoxLayout.X_AXIS));
JLabel lblVolume = new JLabel("Volume");
lblVolume.setForeground(Color.WHITE);
panelVolume.add(lblVolume);
JSlider sliderVolume = new JSlider();
sliderVolume.setBackground(Color.DARK_GRAY);
panelVolume.add(sliderVolume);
sliderVolume.setFocusable(false);
sliderVolume.setValue(10);
JPanel panelLength = new JPanel();
panelLength.setBackground(Color.DARK_GRAY);
panelLength.setLayout(new BoxLayout(panelLength, BoxLayout.X_AXIS));
JLabel lblLength = new JLabel("Length (0.05s)");
lblLength.setForeground(Color.WHITE);
panelLength.add(lblLength);
JSlider sliderLength = new JSlider();
sliderLength.setMaximum(SAMPLE_RATE / 100 * 2);
sliderLength.setBackground(Color.DARK_GRAY);
sliderLength.setSnapToTicks(true);
sliderLength.setValue(22);
sliderLength.setMinimum(22);
panelLength.add(sliderLength);
sliderLength.setFocusable(false);
sliderLength.addChangeListener(e -> {
int size = board.resizeData(sliderLength.getValue());
if (size != -1) {
lblLength
.setText("Length (" + String.format(Locale.ENGLISH, "%.2fs", size / (float) SAMPLE_RATE) + ")");
}
});
controls.setLayout(new BoxLayout(controls, BoxLayout.X_AXIS));
controls.add(panelVolume);
Component spacer = Box.createHorizontalStrut(20);
controls.add(spacer);
controls.add(panelLength);
AudioPlayer player = new AudioPlayer(board::getSampleAt, sliderVolume::getValue);
player.start();
}
}