0

ファイルのさまざまな長さのオーディオのピッチを変更できる既存のオーディオ ファイルを使用してオーディオ ファイルを作成したいと考えています。ファイルが 36 秒の場合のように、最初の 2 秒のピッチを何らかの値で変更し、次に 6 秒から 9 秒まで他の値などを変更します。

基本的に、メッセージk、i、l、bの各文字に従って、ユーザーが「kill bill」と入力した場合など、ユーザーが与えるテキストメッセージに基づいてオーディオファイルを変更しようとしています...私は配列を取得しましたこれにはさまざまな期間が格納されており、26 個のアルファベット a、b、c、d などのテーブルがあります。これらの期間に基づいて、これらの特定の期間のファイルを変更しようとしています。問題は、私が実際にオーディオをうまく操作できていないことです。Java で同じことを試してみましたが、できませんでした。

変更をあまり目立たせずにオーディオファイルで変更できる他のパラメーターはありますか?

コードは Java ですが、無視してください。後で Python でそれを変換します。値はミリ秒単位です。

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; // value in milliseconds 
            }
            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;
            }

        }

    }

今、私はPythonで同じことをしようとしています。私はこの概念に非常に慣れていませんが、この概念で問題に直面したのはこれが初めてです。

4

1 に答える 1

1

簡単な方法は、生の PCM データを直接操作することです。この形式では、オーディオ データは、定期的な間隔 (44100Hz など) でサンプリングされた -32768...32767 値のシーケンス (16 ビット符号付きモノラルを想定) エントリごとに 2 バイトとして格納されます。

ピッチを変更するには、たとえば 45000Hz または 43000Hz でこのデータをより速く「読み取る」ことができます。これはリサンプリング手順で簡単に実行できます。例えば

 import struct
 data = open("pcm.raw", "rb").read()
 parsed = struct.unpack("%ih" % (len(data)//2), data)
 # Here parsed is an array of numbers

 pos = 0.0     # position in the source file
 speed = 1.0   # current read speed = original sampling speed
 result = []

 while pos < len(parsed)-1:
     # Compute a new sample (linear interpolation)
     ip = int(pos)
     v = int(parsed[ip] + (pos - ip)*(parsed[ip+1] - parsed[ip]))
     result.append(v)

     pos += speed     # Next position
     speed += 0.0001  # raise the pitch

 # write the result to disk
 open("out.raw", "wb").write(struct.pack("%ih" % len(result)), result)

これは問題に対する非常に単純なアプローチですが、たとえば、ピッチを大きくすると長さが短くなるため、これを回避するには、単に補間するだけではなく、より高度な計算が必要になることに注意してください。

たとえば、曲の長さを 1 トーン上げるために、このアプローチを使用しました (これが目立つかどうかを確認したかったのですが、そうではありません)。

于 2015-03-19T07:15:08.347 に答える