在下面的Java使用codeS修改在文件特定位置的音频文件的音调 [英] To modify the pitch of an audio file at specific positions in the files using the codes in java below

查看:313
本文介绍了在下面的Java使用codeS修改在文件特定位置的音频文件的音调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要动态地修改基于在不同时刻的用户输入的音频剪辑的音高,说,如果用户输入改变音频的音调10秒后,然后我怎么能达到同样的?

我发现这个链接,描述如何修改球场,但我想在音频剪辑的不同时刻和只有一些短时重复这个过程。任何人都可以指导我一下吗?

部分编辑

修改1

我发现这个code,因为我提到这个previously以及

  //源文件
最终文件文件1 =新的文件(Sample.mp3);
//目标文件
最终文件文件2 =新的文件(Sample_cat.wav);
//文件1的音频流
最终的AudioInputStream IN1 = getAudioInputStream(文件1);
//得到针对性声音频格式
最后AudioFormat的资料,请= getOutFormat(in1.getFormat());
//改变音频格式的频率
私人AudioFormat的getOutFormat(AudioFormat的INFORMAT){
        INT CH = inFormat.getChannels();
        浮动率= inFormat.getSampleRate();
        返回新AudioFormat的(PCM_SIGNED,72000,16,CH,CH * 2,利率,
                inFormat.isBigEndian());
    }
//使用的文件格式获得目标文件的音频流
最终的AudioInputStream IN2 = getAudioInputStream(INFORMAT,IN1);
//编写有针对性的音调文件中的音频文件
AudioSystem.write(IN2,AudioFileFormat.Type.WAVE,文件2);

编辑2
我发现了另一个code这台音频文件从要启动和停止音频的位置。

 文件AUDIOFILE =新的文件(audioFilePath);
        的AudioInputStream语音串流= AudioSystem.getAudioInputStream(AUDIOFILE);        AudioFormat的格式= audioStream.getFormat();        DataLine.Info信息=新DataLine.Info(Clip.class,格式);        剪辑音频剪辑=(剪辑)AudioSystem.getLine(信息);
        audioClip.open(语音串流);
        audioClip.setLoopPoints(10_000,500_000);
        audioClip.loop(1);

现在,我怎样才能改变音高在设定的时间的编辑2 即10毫秒到50使用code以毫秒为单位的编辑1

任何人可以建议我,如果我可以做同样的事情,除了Java的其他方法吗?然后建议,欢迎...
请帮忙。我是新来这个。

**编辑3 **

一个可以参考此链接确切的问题:<一href=\"http://stackoverflow.com/questions/29138169/algorithm-and-package-to-modify-the-pitch-of-the-sound-for-certain-durations-rep?noredirect=1#comment46501513_29138169\">link

这是我指的值(以毫秒为单位):

 公共静态无效convertMsgToAudio(弦乐味精){        INT LEN = msg.length();
        持续时间=新的双[LEN]
        味精= msg.toUpperCase();
        的System.out.println(消息2:+味精);        INT I;
        //字符CH;
        对于(i = 0; I&LT; msg.length();我++){            如果(msg.charAt(I)=='A'){
                持续时间由[i] = 50000;
            }
            否则如果(msg.charAt(ⅰ)==B){
                持续时间由[i] = 100000;
            }
            否则如果(msg.charAt(ⅰ)=='C'){
                持续时间由[i] = 150000;
            }
            否则如果(msg.charAt(ⅰ)=='D​​'){
                持续时间由[i] = 200000;
            }
            否则,如果(msg.charAt(I)=='E'){
                持续时间由[i] = 250000;
            }
            否则如果(msg.charAt(ⅰ)=='F'){
                持续时间由[i] = 300000;
            }
            否则如果(msg.charAt(ⅰ)=='G'){
                持续时间由[i] = 350000;
            }
            否则如果(msg.charAt(ⅰ)=='H'){
                持续时间由[i] = 400000;
            }
            否则如果(msg.charAt(ⅰ)==I){
                持续时间由[i] = 450000;
            }
            否则如果(msg.charAt(ⅰ)=='J'){
                持续时间由[i] = 500000;
            }
            否则如果(msg.charAt(ⅰ)==K){
                持续时间由[i] = 550000;
            }
            否则如果(msg.charAt(ⅰ)==L){
                持续时间由[i] = 600000;
            }
            否则如果(msg.charAt(ⅰ)==M){
                持续时间由[i] = 650000;
            }
            否则如果(msg.charAt(ⅰ)=='N'){
                持续时间由[i] = 700000;
            }
            否则,如果(msg.charAt(I)=='O'){
                持续时间由[i] = 750000;
            }
            否则如果(msg.charAt(ⅰ)==P){
                持续时间由[i] = 800000;
            }
            否则如果(msg.charAt(ⅰ)=='Q'){
                持续时间由[i] = 850000;
            }
            否则如果(msg.charAt(ⅰ)=='R'){
                持续时间由[i] = 900000;
            }
            否则如果(msg.charAt(ⅰ)=='S'){
                持续时间由[i] = 950000;
            }
            否则,如果(msg.charAt(I)=='T'){
                持续时间由[i] = 1000000;
            }
            否则,如果(msg.charAt(我)=='U'){
                持续时间由[i] = 110万;
            }
            否则如果(msg.charAt(ⅰ)==V​​){
                持续时间由[i] = 120;
            }
            否则如果(msg.charAt(ⅰ)=='w'){
                持续时间由[i] = 130万;
            }
            否则如果(msg.charAt(ⅰ)=='X'){
                持续时间由[i] = 140万;
            }
            否则如果(msg.charAt(ⅰ)=='Y'){
                持续时间由[i] = 150万;
            }
            否则如果(msg.charAt(ⅰ)=='Z'){
                持续时间由[i] = 160;
            }        }    }


解决方案

Java不暴露在剪辑片段进行编辑的数据,据我所知。

我从来没有尝试过通过与采样率搞乱改变音高。也许这是一个很好的路要走。还有就是覆盖的WAV文件格式更改了Java教程的一部分:使用文件和格式转换器的。看起来这将是很好的背景信息,甚至可以覆盖你正试图解决方案。

下面是我做的,称之为VarispeedWavPlayer。

(1)具有挥发性的实例浮点型变​​量这是一个速度的因素(1相同的速度,1.1是110%,0.5是半速等等。

(2)有一个浮动,这将是一个正在运行的tapehead

(3)与正常code开始从的AudioInputStream读取,并输出到上述Java教程链接的SourceDataLine(很好的例子,在读声音文件。

(4)在有注释的区域

  //这里做一些事情是这样的音频数据有用
//现在audioBytes阵列中的...

(a)该进来的字节转换成PCM数据。

如何做到这一点,有16位编码,音响,小尾数(CD质量)示例。它使用1024字节读取缓冲区的大小,它转换为介于-32767至32767(或者32768短数据的256帧(记住,有两条轨道,左,右),我不记得是在细节此刻)。

 ,而((读取动作= audioInputStream.read(rawByteBuffer,0,1024))!= -1)
{
    对(INT I = 0,N =读取动作/ 2); I&LT; N;我++)
    {
        pcmBuffer [I] =(rawByteBuffer [我* 2]安培;为0xFF)
                        | (rawByteBuffer [(我* 2)+ 1)]&所述;&下; 8);
    }
}

以上编辑为清晰,并且可以使用一些性能优化。

(二)获取当前speedfactor,写一个循环,通过PCM帧值迭代(牢记立体声,下一个框架的曲目是+2):

  tapehead + = speedfactor;

(三),这将通常降落在一个分数值。使用线性内插在该中间点来计算的值。例如,如果你降落在tapehead = 10.25,和帧10为0.5,框架11为0.6,你会回到0.525。

(D)转换插值回字节(步骤4a的反向)

(五)累计字节,并通过SourceDataLine的发送出去。

我省略了一些细节在管理的事实,即输入和输出的ByteBuffers将不匹配的一对一的条款。但是,如果你掌握的基本概念,那么我认为你将能够解决这个问题。

请注意,这只会在点当speedFactor变量征求意见,每输入缓冲区一次更新的速度。所以,你不想输入缓冲区过于大。

I want to modify the pitch of the audio clip dynamically based on the user input at different time instants, say if user enters change the pitch of the audio after 10 seconds then how can I achieve the same?

I found this link that describes how to modify the pitch but i want to repeat this process at different time instants of the audio clip and for some short duration only. Can anybody guide me on this ?

Some Edits

Edit 1

I found this code as I mentioned this previously as well

//source file
final File file1 = new File("Sample.mp3");
//destination file
final File file2 = new File("Sample_cat.wav");
//audio stream of file1
final AudioInputStream in1 = getAudioInputStream(file1);
//get audio format for targetted sound
final AudioFormat inFormat = getOutFormat(in1.getFormat());
//change the frequency of Audio format
private AudioFormat getOutFormat(AudioFormat inFormat) {
        int ch = inFormat.getChannels();
        float rate = inFormat.getSampleRate();    
        return new AudioFormat(PCM_SIGNED, 72000, 16, ch, ch * 2, rate,
                inFormat.isBigEndian());
    }
//get the target file audio stream using file format
final AudioInputStream in2 = getAudioInputStream(inFormat, in1);
//write the audio file in targeted pitch file
AudioSystem.write(in2, AudioFileFormat.Type.WAVE, file2);

EDIT 2 I found another code which sets the position of audio file from where you want to start and stop the audio.

        File audioFile = new File(audioFilePath);


        AudioInputStream audioStream = AudioSystem.getAudioInputStream(audioFile);

        AudioFormat format = audioStream.getFormat();

        DataLine.Info info = new DataLine.Info(Clip.class, format);

        Clip audioClip = (Clip) AudioSystem.getLine(info); 
        audioClip.open(audioStream);
        audioClip.setLoopPoints(10_000, 500_000);
        audioClip.loop(1);

Now, How can I change the pitch for the duration set in Edit 2 i.e. 10 ms to 50 ms using the code in Edit 1

can anybody suggest me if I can do the same thing in any other ways except Java ? then suggestions are welcome... Please Help. I am new to this.

**Edit 3 **

One can refer the exact problem on this link : link

These are the values(in milliseconds) that I am referring :

public static void convertMsgToAudio(String msg){

        int len = msg.length();
        duration = new double[len];
        msg = msg.toUpperCase();
        System.out.println("Msg 2 : " + msg);

        int i;
        //char ch;
        for(i=0;i<msg.length();i++){

            if(msg.charAt(i) == 'A'){
                duration[i] = 50000;
            }
            else if (msg.charAt(i) == 'B'){
                duration[i] = 100000;
            }
            else if (msg.charAt(i) == 'C'){
                duration[i] = 150000;
            }
            else if (msg.charAt(i) == 'D'){
                duration[i] = 200000;               
            }
            else if (msg.charAt(i) == 'E'){
                duration[i] = 250000;
            }
            else if (msg.charAt(i) == 'F'){
                duration[i] = 300000;
            }
            else if (msg.charAt(i) == 'G'){
                duration[i] = 350000;
            }
            else if (msg.charAt(i) == 'H'){
                duration[i] = 400000;
            }
            else if (msg.charAt(i) == 'I'){
                duration[i] = 450000;
            }
            else if (msg.charAt(i) == 'J'){
                duration[i] = 500000;
            }
            else if (msg.charAt(i) == 'K'){
                duration[i] = 550000;
            }
            else if (msg.charAt(i) == 'L'){
                duration[i] = 600000;
            }
            else if (msg.charAt(i) == 'M'){
                duration[i] = 650000;
            }
            else if (msg.charAt(i) == 'N'){
                duration[i] = 700000;
            }
            else if (msg.charAt(i) == 'O'){
                duration[i] = 750000;
            }
            else if (msg.charAt(i) == 'P'){
                duration[i] = 800000;
            }
            else if (msg.charAt(i) == 'Q'){
                duration[i] = 850000;
            }
            else if (msg.charAt(i) == 'R'){
                duration[i] = 900000;
            }
            else if (msg.charAt(i) == 'S'){
                duration[i] = 950000;
            }
            else if (msg.charAt(i) == 'T'){
                duration[i] = 1000000;
            }
            else if (msg.charAt(i) == 'U'){
                duration[i] = 1100000;
            }
            else if (msg.charAt(i) == 'V'){
                duration[i] = 1200000;
            }
            else if (msg.charAt(i) == 'W'){
                duration[i] = 1300000;
            }
            else if (msg.charAt(i) == 'X'){
                duration[i] = 1400000;
            }
            else if (msg.charAt(i) == 'Y'){
                duration[i] = 1500000;
            }
            else if (msg.charAt(i) == 'Z'){
                duration[i] = 1600000;
            }

        }

    }

解决方案

Java does not expose the data in a Clip for editing, as far as I know.

I've never tried altering the pitch by messing with the sample rate. Maybe that is a good way to go. There is a section of the Java tutorials that covers changes in formatting of wav files: Using Files and Format Converters. Seems like this would be good background info and may even cover the solution you are attempting.

Here is what I do, call it a VarispeedWavPlayer.

(1) have a volatile instance float variable that is a speed factor (1 is same speed, 1.1 is 110%, 0.5 is half speed, etc.

(2) have a float that will be a running 'tapehead'

(3) start with normal code for reading in from an AudioInputStream and outputting to a SourceDataLine (good example in "Reading Sound Files" in the above Java Tutorial link.

(4) in the area where there is the comment

// Here, do something useful with the audio data that's 
// now in the audioBytes array...

(a) convert the incoming bytes to PCM data.

Example of how to do this, with 16-bit encoding, stereo, little-endian ("CD quality"). This uses a read buffer size of 1024 bytes, which converts to 256 frames (remember, there are two tracks, left and right) of short data that ranges from -32767 to 32767 (or maybe 32768, I can't recall that detail at the moment).

while((bytesRead = audioInputStream.read(rawByteBuffer, 0, 1024)) != -1)
{
    for (int i = 0, n = bytesRead / 2); i < n; i ++)
    {
        pcmBuffer[i] =  ( rawByteBuffer[i * 2] & 0xff )
                        | ( rawByteBuffer[(i * 2) + 1)] << 8 ) ;
    }
}   

The above was edited to be clear, and can use some performance optimizations.

(b) fetch the current "speedfactor" and write a loop that iterates through the PCM frame values (keeping in mind that with stereo, the "next" frame for that track is +2):

tapehead += speedfactor;

(c) this will usually land at a fractional value. Use linear interpolation to calculate a value at that intermediate spot. For example, if you land at tapehead = 10.25, and frame 10 is 0.5, and frame 11 is 0.6, you'd return 0.525.

(d) convert the interpolated values back to bytes (reverse of step 4a)

(e) accumulate the bytes and send them out via the SourceDataLine.

I've left out some details in terms of managing the fact that the input and output bytebuffers will not match one-to-one. But if you grasp the basic concept, then I think you will be able to solve this.

Note, this will only update the speed at the point when the "speedFactor" variable is consulted, once per input buffer. So you don't want the input buffer to be overly large.

这篇关于在下面的Java使用codeS修改在文件特定位置的音频文件的音调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆