- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试执行汉明运算,然后对 wav 文件执行 FFT。我已经在 python 中实现了相同的功能。如何在 Java 中执行此操作。我已经在给定的波形文件上应用了汉明,它返回一个 bytearrayOutputStream。现在如何对该 byteArrayOutputStream 执行 FFT?我是音频处理新手。我当前的代码是:
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
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.sound.sampled.UnsupportedAudioFileException;
public class AudioFFT {
public static void main(String[] args) throws UnsupportedAudioFileException, IOException {
String wavFilePath="C:\\abc.wav";
ByteArrayOutputStream byteArrayOutputStream=applyHamming(wavFilePath);
byte[] bytesOut=byteArrayOutputStream.toByteArray();
System.out.println(Arrays.toString(bytesOut));
}
public static ByteArrayOutputStream applyHamming(String filePath)
{
// TODO Auto-generated method stub
ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
File fileIn = new File(filePath);
AudioInputStream audioInputStream;
try {
audioInputStream = AudioSystem.getAudioInputStream(fileIn);
int bytesPerFrame = audioInputStream.getFormat().getFrameSize();
if (bytesPerFrame == AudioSystem.NOT_SPECIFIED) {
bytesPerFrame = 1;
}
int numBytes = 1024 * bytesPerFrame;
byte[] audioBytes = new byte[numBytes];
int numBytesRead = 0;
while ((numBytesRead = audioInputStream.read(audioBytes, 0, audioBytes.length)) != -1) {
outputStream.write(audioBytes, 0, numBytesRead);
}
} catch (UnsupportedAudioFileException | IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return outputStream;
}
private static int BITS_IN_BYTE = 8;
private static AudioInputStream audioInputStream;
private static AudioFormat format;
final static int W = 1024;
public static void getFFT() {
String wavFilePath="C:\\abc.wav";;
File AudioFile = new File(wavFilePath);
ByteArrayOutputStream out = new ByteArrayOutputStream();
BufferedInputStream in;
try {
audioInputStream = AudioSystem.getAudioInputStream(AudioFile);
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
format = audioInputStream.getFormat();
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
if (!AudioSystem.isLineSupported(info)) {
System.out.println("Error");
}
TargetDataLine line = null;
try {
line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format);
} catch (LineUnavailableException ex) {
System.out.println("Error");
}
line.start();
byte[] data = new byte[W * format.getSampleSizeInBits() / BITS_IN_BYTE];
double[] inbuf = new double[W];
double[] fftbuf = new double[W];
try {
in = new BufferedInputStream(new FileInputStream(AudioFile));
int read;
while ((read = in.read(data)) > 0) {
out.write(data, 0, read);
}
out.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
data = out.toByteArray();
decode(data, inbuf);
fft(inbuf, fftbuf);
}
public static void decode(byte[] input, double[] output) {
assert input.length == 2 * output.length;
for (int i = 0; i < output.length; i++) {
output[i] = (short) (((0xFF & input[2 * i + 1]) << 8) | (0xFF & input[2 * i]));
output[i] /= Short.MAX_VALUE;
}
}
public static void fft(final double[] inputReal, double[] inputImag) {
assert inputReal.length == 2 * inputImag.length;
int n = inputReal.length;
double ld = Math.log(n) / Math.log(2.0);
if (((int) ld) - ld != 0) {
System.out.println("The number of elements is not a power of 2.");
}
int nu = (int) ld;
int n2 = n / 2;
int nu1 = nu - 1;
double[] xReal = new double[n];
double[] xImag = new double[n];
double tReal, tImag, p, arg, c, s;
double constant;
if (true){
constant = -2 * Math.PI;
}
for (int i = 0; i < n; i++) {
xReal[i] = inputReal[i];
xImag[i] = inputImag[i];
}
int k = 0;
for (int l = 1; l <= nu; l++) {
while (k < n) {
for (int i = 1; i <= n2; i++) {
p = bitreverseReference(k >> nu1, nu);
arg = constant * p / n;
c = Math.cos(arg);
s = Math.sin(arg);
tReal = xReal[k + n2] * c + xImag[k + n2] * s;
tImag = xImag[k + n2] * c - xReal[k + n2] * s;
xReal[k + n2] = xReal[k] - tReal;
xImag[k + n2] = xImag[k] - tImag;
xReal[k] += tReal;
xImag[k] += tImag;
k++;
}
k += n2;
}
k = 0;
nu1--;
n2 /= 2;
}
k = 0;
int r;
while (k < n) {
r = bitreverseReference(k, nu);
if (r > k) {
tReal = xReal[k];
tImag = xImag[k];
xReal[k] = xReal[r];
xImag[k] = xImag[r];
xReal[r] = tReal;
xImag[r] = tImag;
}
k++;
}
double[] newArray = new double[xReal.length * 2];
double radice = 1 / Math.sqrt(n);
for (int i = 0; i < newArray.length; i += 2) {
int i2 = i / 2;
newArray[i] = xReal[i2] * radice;
newArray[i + 1] = xImag[i2] * radice;
}
for (int i = 0; i < newArray.length; i++) {
System.out.println("Array: " + newArray[i]);
}
}
private static int bitreverseReference(int j, int nu) {
int j2;
int j1 = j;
int k = 0;
for (int i = 1; i <= nu; i++) {
j2 = j1 / 2;
k = 2 * k + j1 - 2 * j2;
j1 = j2;
}
return k;
}
}
最佳答案
bytesOut
包含您的 wav 文件数据(经过Hamming window
函数修改后)。这些数据表示您应发送到 fft
方法的实数部分
(inputReal
)。对于虚部,创建一个与 inputReal 大小相同的数组并用零填充它
//为虚部创建一个数组(我假设长度为1024)
double[] imgBytesOut = new double[1024]; //imgBytesOut is not a good name for this
for(int i=0; i<1024;i++)
imgBytesOut[i] = 0;
现在您已拥有调用 fft 所需的一切
fft(bytesOut, imgBytesOut);
您的 fft 方法填充 xReal
和 xImg
数组,但由于您在本地声明了它们,因此您不会能够在 fft 完成后使用它们(将它们声明为静态全局变量)。
此外,如果您的文件包含 10000 个样本,并且您的 fft 大小
的长度为 1024 个样本(outBytes
和 imgBytesOut
的长度为 1024 个样本)您必须重复调用 fft
才能处理整个文件。为了获得最佳结果,您仍然需要应用重叠
(例如,对于 50% 重叠和 1024 的 fft 大小,您需要处理样本 1-1024
,然后是 512-1536
,然后是 1024-2048
等等)。
关于java - 在 Java 中应用 Hamming,然后对 wav 文件进行 FFT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48004859/
如果已知该确切样本存在于 wav 中的某处(但可能与其他声音混合),是否可以使用 FFT 找到较长 wav 中出现的小 wav 样本? 编辑 (收到两个回复后):如果我有一个包含所有已知声音的库,这些
我对 .NET 中的音频完全陌生,所以请多多包涵。 我的目标是创建一个具有两个 channel 的 wav 文件。左声道将包含语音消息(使用 SpeechSynthesizer 生成的流),右声道需要
我的大部分信息都来自其他stackoverflow帖子,但没有一个真正有用。 import UIKit import AVFoundation class FaceButtonSc
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 3 年前。
这可能是一个非常简单的问题;我将一个单声道 WAV 文件转换为一个 short[] 数组,并且我有一个将其写回 WAV 文件的函数。一切正常。 (writeBuffer 是 short[] 数组) b
我们的应用程序需要知道它加载的音频文件的样本数。我们使用的库可以可靠地确定采样率,但不能确定样本数。我们是否可以仅从文件大小和采样率来计算样本数? 最佳答案 马克说什么。不,通常您需要解释标题。但是,
我正在用java做一个项目,需要我加密wave文件。那么,是否有一个直接的过程可以将波形文件转换为二进制文件并返回?我将对二进制数据应用加密算法。 最佳答案 是的。 File file = new F
我想知道如何从 .wav 文件中获取样本以执行两个 .wav 文件的窗口连接。 谁能告诉我怎么做? 最佳答案 wave标准库的模块是关键:当然在代码顶部的 import wave 之后,wave.op
我有一个几分钟长的 .wav 文件,我想将其分成不同的 10 秒 .wav 文件。 到目前为止,这是我的 python 代码: import wave import math def main(fil
我在 ffmpeg 中使用以下命令合并多个 wav 文件: -f concat -safe 0 -i /storage/emulated/0/AudioClipsForSpeakerRecogniti
我正在尝试用python实现主动降噪。我的项目由两组代码组成: 录音代码 声音过滤代码 我的目标是当您运行该程序时,它将开始通过麦克风录音。录音完成后,会生成一个名为“file1.wav”的保存文件,
我正在尝试制作一个音乐识别系统。我担心我可能没有按照预期读取 wav 样本,而且我可能会应用错误的窗口大小来进行 FFT 和其他操作。 如果你能帮我的话,那就太好了。 首先,我有一些关于 Wavs 中
如何使用 java 合并两个 wav 文件? 我试过了 this但它没有正常工作,他们还有其他方法吗? 最佳答案 如果您直接处理 wav 文件的字节,您可以在任何编程语言中使用相同的策略。对于此示例,
尝试为我的 previous question 找到解决方法,我想将用 byte[](具有 wav header )编写的 16k 8 位单声道 wav 转换为 8k 8 位单声道流/字节 []。 是
目前我正在使用一个语音到文本的翻译模型,该模型采用 .wav 文件并将音频中的可听语音转换为文本转录本。该模型之前曾用于直接录制的 .wav 音频录音。但是现在我正在尝试对视频中最初出现的音频做同样的
试图在 python 中将 wav 文件转换为 wav uLaw。 使用 pydub 的 AudioSegment,我可以使用以下命令转换为 mp3: AudioSegment.from_wav(fr
我在 xcode 项目中添加了 LibFlac。然后我在我的项目中添加了来自 Libflac 的decode/main.c。我通过了 infile.flac 并运行了项目的可执行文件,但它给出了以下错
大家好,感谢您的阅读。 我想使用 Python 的 scipy.io.wavfile 对一首歌进行一些分析。由于我只有 .mp3 格式的歌曲,因此我使用 ffmpeg 将文件转换为 .wav,方法如下
我需要连接两个音频波,以便最终输出的音频波应该有一个更平滑的交汇点。我的意思是,在连接点,假设 10 秒钟,第一个音频应该开始淡出,而另一个音频开始拾取。 我已经能够连接两个音频文件并生成单个输出,但
我需要将一个 wav 文件转换为 8000Hz 16 位单声道 Wav。我已经有一个代码,它适用于 NAudio 库,但我想使用 MemoryStream 而不是临时文件。 using System.
我是一名优秀的程序员,十分优秀!