나는 사운드 디지털화에 대해 많이 모른다. 마이크 입력의 즉각적인 프로파일을 나타 내기 위해 노력하고 있습니다. 마이크에서 비트를 얻는 방법을 알고 있지만 프로파일로 해석하는 방법을 모르겠습니다. 누구든지 공백을 채울 수 있습니까? 마이크 입력의 프로파일을 그리시오
package test;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.io.OutputStream;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/**
*
* @author François Billioud
*/
public class SoundRecorder extends JFrame {
/** JFrame for the GUI **/
public SoundRecorder() {
super("Sound Recorder");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container pane = getContentPane();
pane.setLayout(new BorderLayout());
pane.add(wavePane = new WavePane(), BorderLayout.CENTER);
pane.add(new JButton(new AbstractAction("ok") {
@Override
public void actionPerformed(ActionEvent e) {
dispose();
}
}), BorderLayout.SOUTH);
setSize(300,300);
setLocationRelativeTo(null);
}
/** Just displays the frame and starts listening **/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SoundRecorder rec = new SoundRecorder();
rec.setVisible(true);
rec.listenToMic();
}
});
}
/** Draws the sound read from the mic **/
private static class WavePane extends JPanel {
private final int[] x = new int[0];
private int[] y = new int[0];
private WavePane() {
setOpaque(true);
setBackground(Color.WHITE);
}
/** updates the data to be displayed **/
public void setData(int[] y) {
this.y = y;
int n = y.length;
this.x = new int[n];
float pas = getWidth()/(float)(n-1);
float xCurrent = 0;
for(int i=0; i<n; i++) {
this.x[i] = Math.round(xCurrent);
xCurrent+=pas;
}
repaint();
}
/** Draws a line that represent the mic profile **/
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2D = (Graphics2D) g;
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2D.drawPolyline(x, y, x.length);
}
}
/** Defines the audio format to be used.
* I know nothing about that and am open to suggestions if needed
*/
private static final AudioFormat format = new AudioFormat(
16000, //Sample rate
16, //SampleSizeInBits
2, //Channels
true,//Signed
true //BigEndian
);
/** Creates a thread that will read data from
* the mic and send it to the WavePane
* in order to be painted.
* We should be using a SwingWorker, but it will do
* for the sake of this demo.
**/
private void listenToMic() {
new Thread(new Runnable() {
@Override
public void run() {
try {
//Open the line and read
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
//checks if system supports the data line
if (!AudioSystem.isLineSupported(info)) {
System.err.print("Line not supported");
}
//starts listening
TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format);
line.start();
//sends the stream to the interpreter
AudioInputStream ais = new AudioInputStream(line);
AudioSystem.write(ais, AudioFileFormat.Type.AU, new Interpreter());
} catch (LineUnavailableException | IOException ex) {
System.err.println(ex.getLocalizedMessage());
}
}
}).start();
}
private final WavePane wavePane;
private class Interpreter extends OutputStream {
private int[] y;
@Override
public void write(int b) throws IOException {
//TBD
//Fill y array
}
@Override
public void flush() throws IOException {
//Sends the values found to the panel for drawing
wavePane.setData(y);
}
}
}
내가
this link을 발견하지만
편집 ... 나에게 도움이되지 않았다 : 좋아, 각각 16 비트, 내가 이해에서 하나 개의 주파수에 대한 진폭이다. 저는 2 채널을 가지고 있으므로 첫 채널을 얻기 위해 매 32 비트마다 32 비트를 읽어야합니다. 이제 각 프레임에 대해 얼마나 많은 주파수를 읽어야하는지 알 필요가 있습니다. 그런 다음 프로파일을 그릴 수 있다고 생각합니다. 어떤 힌트?
매우 완벽한 링크를 제공해 주셔서 감사합니다. 실시간으로 마이크에서 주파수 당 에너지를 끌어오고 싶습니다. 링크는 좋지만 마이크 입력을 비트로 변환 할 때 STFT가 완료됩니다. 질문은 스트림을 읽었을 때 스트림에서 데이터가 정렬되는 방식과 내 표현을 얻기 위해 데이터를 다시 정렬해야하는 방식에 관한 것입니다. 무슨 뜻인지 알 겠어? – Sharcoux
응답 내용에 스트림 내용에 대한 설명을 추가했습니다. – astraujums
확인. 나는 단지 몇 가지 더 많은 정보를 가지고 있다고 생각합니다. 음수를 어떻게 해석해야합니까? 에너지는 음수가 될 수 없으므로 -3000은 PI의 단계에서 3000을 의미한다고 생각하십니까? 그렇다면 절대 값을 고려해야합니까? 빅 엔디안 부호없는 형식의 바이트 배열'byte [16]'을 가지고 있다면 그것을 숫자로 변환하는 올바른 방법은 무엇입니까? 당신의 도움을 주셔서 대단히 감사합니다! – Sharcoux