Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用下面的java代码在文件中的特定位置修改音频文件的音调_Java_Audio_Time_Javasound_Pitch - Fatal编程技术网

使用下面的java代码在文件中的特定位置修改音频文件的音调

使用下面的java代码在文件中的特定位置修改音频文件的音调,java,audio,time,javasound,pitch,Java,Audio,Time,Javasound,Pitch,我想根据用户在不同时刻的输入动态修改音频片段的音高,比如说,如果用户在10秒后输入更改音频的音高,那么我如何实现相同的效果 我发现这描述了如何修改音高,但我想在音频剪辑的不同时刻重复这个过程,并且只在短时间内重复。有谁能给我指点迷津吗 一些编辑 编辑1 我发现了这段代码,正如我之前提到的 //source file final File file1 = new File(“Sample.mp3”); //destination file final File file2 = new File(“

我想根据用户在不同时刻的输入动态修改音频片段的音高,比如说,如果用户在10秒后输入更改音频的音高,那么我如何实现相同的效果

我发现这描述了如何修改音高,但我想在音频剪辑的不同时刻重复这个过程,并且只在短时间内重复。有谁能给我指点迷津吗

一些编辑

编辑1

我发现了这段代码,正如我之前提到的

//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);
编辑2 我发现了另一个代码,它设置音频文件的位置,从那里开始和停止音频

        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);
现在,我如何使用编辑1中的代码将编辑2中设置的持续时间(即10 ms到50 ms)更改为音高


有人能建议我,除了Java以外,我还能用其他方式做同样的事情吗?那么欢迎您的建议。。。 请帮忙。我是新来的

**编辑3**

您可以在此链接上查看确切的问题:

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

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;
            }

        }

    }
publicstaticvoidconvertmsgtoudio(字符串msg){
int len=msg.length();
持续时间=新的双倍[len];
msg=msg.toUpperCase();
System.out.println(“Msg 2:+Msg”);
int i;
//char ch;

就我所知,for(i=0;iJava不公开剪辑中的数据进行编辑

我从未尝试过通过改变采样率来改变音高。也许这是一个很好的方法。Java教程中有一节介绍了wav文件格式的更改:。这似乎是一个很好的背景信息,甚至可能涵盖了您正在尝试的解决方案

这就是我所做的,称之为一个变形金刚

(1) 有一个可变的实例浮点变量,它是一个速度因子(1是相同的速度,1.1是110%,0.5是半速度,等等)

(2) 有一个浮动,它将是一个运行的“tapehead”

(3) 从普通代码开始,从AudioInputStream读入并输出到SourceDataLine(在上面的Java教程链接中的“读取声音文件”中有一个很好的例子)

(4) 在有评论的区域

// Here, do something useful with the audio data that's 
// now in the audioBytes array...
(a) 将传入字节转换为PCM数据

例如,使用16位编码、立体声、little-endian(“CD质量”)。这使用了1024字节的读取缓冲区大小,可转换为256帧(请记住,有两个轨道,左侧和右侧)的短数据,范围从-32767到32767(或者32768,我现在记不起该细节)

(c) 这通常会在小数点处着陆。使用线性插值计算中间点处的值。例如,如果在tapehead=10.25处着陆,第10帧为0.5,第11帧为0.6,则返回0.525

(d) 将插值转换回字节(与步骤4a相反)

(e) 累积字节并通过SourceDataLine发送它们

我已经略去了一些细节,关于如何管理这样一个事实,即缓冲区的输入和输出不会一一匹配。但是如果你掌握了基本概念,那么我认为你将能够解决这个问题


注意,这只会在参考“speedFactor”变量时更新速度,每个输入缓冲区更新一次。因此,您不希望输入缓冲区过大。

在这方面没有人能帮我吗?有人能建议我是否可以用Java以外的任何其他方式做同样的事情吗?欢迎提供建议……感谢您的回复:)但是我还没有很好地掌握音频…特别是我不知道如何将传入的数据转换为PCM数据…和后记…所以如果你能为我提供这方面的代码,而不是伪代码,这将是一个很大的帮助…因为我的时间不多了,我不是很擅长java…但没有其他选择…每个步骤都有已经在StackOverflow上讨论过了。我想如果你搜索它们,你会获得一些成功。我的时间也很短。可能是因为你比你准备的要多了一点,因为这需要的不仅仅是Java编码的初学者技能水平。谢谢你的建议,我会在这方面做一些工作。你能告诉我一件事吗,…我您是否可以告诉我您所说的方式是否有助于我实现这一点?提前感谢:)要获取两个字节(假设16位编码,小尾端)并转换为范围从-32767到32767的PCM,请尝试以下代码行:int audioVal=(缓冲区[i+1]
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 ) ;
    }
}   
tapehead += speedfactor;