【问题标题】:convert a wav file to a txt file将wav文件转换为txt文件
【发布时间】:2014-11-05 23:49:07
【问题描述】:

感谢您阅读本文 那么我要做的是获取一个.wav文件(只有一个短音频)并将其转换为整数,每个都代表音频的音调...... 如果你问我为什么要这样做,是因为我正在做一个 arduino 项目,我想让 arduino 播放歌曲,为此我需要一个 int 数组,其中每个 int 都是一个音调。 所以我想,“如果我编写一个小应用程序来将任何 .wav 文件转换为存储代表旋律音符的整数的 txt,我只需将这些值复制到 arduino 项目代码”; 所以在这一切之后,也许你在问“你的问题是什么?”; 我完成了代码并且正在“工作”,唯一的问题是 txt 在每一行中只有“1024”...... 所以很明显我有问题,不是所有的音调都是1024 -_-

package WaveToText;

import java.io.*;

/**
*
* @author  Luis Miguel Mejía Suárez
* @project This porject is to convert a wav music files to a int array
*          Which is going to be printed in a txt file to be used for an arduino
* @serial  1.0.1 (05/11/201)
*/

public final class Converter 
{
/**
 * 
 * @Class Here is where is going to be allowed all the code for the application
 * 
 * @Param Text is an .txt file where is going to be stored the ints
 * @Param MyFile is the input of the wav file to be converted
 */

PrintStream Text;
InputStream MyFile;

public Converter () throws FileNotFoundException, IOException
{
        MyFile = new FileInputStream("C:\\Users\\luismiguel\\Dropbox\\ESTUDIO\\PROGRAMAS\\JAVA\\WavToText\\src\\WaveToText\\prueba.wav");
        Text = new PrintStream(new File("Notes.txt"));
}

public void ConvertToTxt() throws IOException
{
    BufferedInputStream in = new BufferedInputStream(MyFile);

    int read;

    byte[] buff = new byte[1024];
    while ((read = in.read(buff)) > 0)
    {
        Text.println(read);
    }
    Text.close();
}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) throws IOException{
    // TODO code application logic here
    Converter Exc = new Converter();
    Exc.ConvertToTxt();        
}

}

【问题讨论】:

  • 您的一般方法一开始并不完全正确。 WAV 文件存储时域数据;也就是说,信号与时间的关系(例如,440 Hz 的音调可能是,例如,WAV 文件中 440 Hz 正弦波的样本值)。您对“音调”的概念是频域的;也就是说,信号强度与频率。您需要执行某种类型的频率分析(查找离散 FFT)以从 WAV 文件中的原始波形中提取“旋律”信息,或者您需要修改硬件端并让 Arduino 播放原始数字音频参数化频率。
  • 顺便说一下,对于文件格式本身,it is well-documented,还有一个很好的读取数据的例子here。但是,您最好使用已经为您完成工作的AudioInputStream(并且支持除 WAV 之外的格式)。另请参阅 sweb.cityu.edu.hk/sm1204/2012A/page20/index.html,它描述了一些与 Java Sound API 集成的 FFT 库。
  • 无论该方法是否正确,我已在答案中提供了您的代码的问题。希望对您有所帮助。
  • 嗯,我已经尝试过你(CharlieS)所说的“类似”的东西,我说类似是因为输出文件完全相同,而且这有很多不同的数字,但不是真的我所期待的;我认为是因为 Alexander 说的,所以我会尝试这种方式......我也尝试了 AudioInputStream,但我得到了“UnsupportedAudioFileException”无论如何感谢很多人的帮助

标签: java audio wav


【解决方案1】:

等等等等……很多东西都不在这里…… 您不能只读取字节并将它们发送到 Arduino,因为正如您所说,Arduino 需要注释编号。 Wav 文件中的数字首先是带有音频信息的“标题”,然后是表示信号中离散点的数字(波形)。如果您想获取音符,则需要一些用于音高检测或音乐转录的算法。
如果您的音乐是单声道或接近单声道,则音高检测可能会起作用。对于全乐队的歌曲,这将是麻烦的。
所以...
我猜“Arduino 部分”会播放单声道音乐,你需要在特定的时刻提取信号的基频(这称为音高检测,有不同的方法可以做到它(自相关、amdf、谱分析))。您还必须保持笔记的时间。

当您提取频率时,有一个公式可以将频率转换为表示钢琴音符编号的整数。 n=12(log2(f/440)) + 49 其中 n 是整数音符编号,f 是音符的基频。在计算之前,您还应该量化从音高识别算法获得的频率到最接近的频率(谷歌以获得确切的音符频率)。

但是我真的建议做更多的研究。在几乎没有乐器演奏的音乐中检测音符真的很困难,鼓,歌手,所有在一起....

【讨论】:

    【解决方案2】:
    while ((read = in.read(buff)) > 0)
    {
        Text.println(read);
    }
    

    这段代码从in读取1024字节的数据,然后将读取的字节数赋值给read,也就是1024,直到文件结束。然后将read 打印到您的文本文件中。

    您可能想将buff 打印到您的文本文件中,但这将写入 1024 个字节,而不是您想要的 1024 个整数。

    您需要创建一个 for 循环以将单个字节打印为整数。

    while ((read = in.read(buff)) > 0)
    {
        for (int i = 0; i < buff.length; i++) 
            Text.print((int)buff[i]);
    }
    

    【讨论】:

      猜你喜欢
      • 2016-10-02
      • 2020-09-22
      • 1970-01-01
      • 2011-06-19
      • 2020-04-22
      • 1970-01-01
      • 1970-01-01
      • 2016-06-19
      • 2019-08-29
      相关资源
      最近更新 更多