如何在Android中将男声录音转换为女声?

时间:2014-03-07 06:16:00

标签: android soundpool voice-recording android-audiorecord

我正在录制男声,当我点击播放按钮时如何将男声转换为女声并以女声播放。我引用了一些我试过sound pool的链接,通过改变浮动速率来改变声音,但我没有得到女性的声音,也没有改变音轨的频率。

这是我的代码:

           soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
            soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
              @Override
              public void onLoadComplete(SoundPool soundPool, int sampleId,
                  int status) {
                loaded = true;
              }
            });
            soundID = soundPool.load(mFileName, 1);


            AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
              float actualVolume = (float) audioManager
                  .getStreamVolume(AudioManager.STREAM_MUSIC);
              float maxVolume = (float) audioManager
                  .getStreamMaxVolume(AudioManager.STREAM_MUSIC);
              float volume = actualVolume / maxVolume;
             /* if (loaded) {
                  iv.setImageDrawable(getResources().getDrawable(R.drawable.palyrec));
                  soundPool.play(soundID, volume, volume, 1, 0, 1.8f);
                  Log.e("Test", "Played sound");
              }*/
              int streamID = -1;
              do {

                  iv.setImageDrawable(getResources().getDrawable(R.drawable.palyrec));
                  streamID = soundPool.play(soundID, volume, volume, 1, 0, 1.7f);
                  Log.e("Test", "Played sound");


              } while(streamID==0);

更改频率代码:        Integer [] freqset = {11025,16000,22050,44100};

   File file = new File(Environment.getExternalStorageDirectory(), "test.pcm");

    int shortSizeInBytes = Short.SIZE/Byte.SIZE;

    int bufferSizeInBytes = (int)(file.length()/shortSizeInBytes);
    short[] audioData = new short[bufferSizeInBytes];

    try {
        InputStream inputStream = new FileInputStream(file);
        BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
        DataInputStream dataInputStream = new DataInputStream(bufferedInputStream);

        int i = 0;
        while(dataInputStream.available() > 0){
            audioData[i] = dataInputStream.readShort();
            i++;
        }

        dataInputStream.close();

        int sampleFreq = (Integer)spFrequency.getSelectedItem();

        AudioTrack audioTrack = new AudioTrack(
                AudioManager.STREAM_MUSIC,
                sampleFreq,
                AudioFormat .CHANNEL_CONFIGURATION_MONO,
                AudioFormat.ENCODING_PCM_16BIT,
                bufferSizeInBytes,
                AudioTrack.MODE_STREAM);

       audioTrack.play();

audioTrack.write(audioData,0,bufferSizeInBytes);

如何在android中转换为女声?

2 个答案:

答案 0 :(得分:2)

我认为对术语频率可能存在误解:采样率频率与感知音高频率不同。

更改采样率频率会改变音高和时间,就像录音带播放得更快(对于那些足够记忆的人来说:-))。

向上改变音高将让它听起来更快,但你会很快注意到引入的数字假象(花栗鼠语音)。

向下时可能听起来好一点(如Luka的视频)。

但是,在这两种情况下,你必须应用的音高变化非常剧烈,会产生一些奇怪的副作用。

最接近的是查看由专门协调或调整签名声乐轨道的软件获得的结果。这些软件看着共振峰,不改变它们来改变音高。

例如为: https://documentation.apple.com/en/logicstudio/effects/index.html#chapter=10%26section=3%26tasks=true

最着名的软件之一: http://www.celemony.com/en/melodyne/what-is-melodyne

我认为在这种情况下,你可能想稍微改变声音的一些共振峰(它包含我们大脑用来识别某人声音的一些特征)和整体音高但是独立。

另请注意,共振峰编号(F0,F1,F2,F3,...),F1和F2可让我们分辨出元音之间的差异。 http://home.cc.umanitoba.ca/~krussll/phonetics/acoustic/formants.html

正如Merlevede所说,我相信一个适合所有人的算法很难实现。

Afaict,android上没有库做这个......

答案 1 :(得分:1)

您需要使用频率。根据:http://en.wikipedia.org/wiki/Voice_frequency

http://www.axiomaudio.com/blog/audio-oddities-frequency-ranges-of-male-female-and-children%E2%80%99s-voices/

男声的频率为85至180 Hz,而女声的频率为165至255 Hz。从这一点来说,如果你简单地增加整体声音频率,你可能会得到类似女性的声音。

以上不会给你一个完美的结果。要获得完美的结果,您需要进行更多研究。您也可以通过反复试验获得此信息。让男性说一些话。让女性说一些话。现在,比较频率。显然,每个人的声音频率都不同。

最后,观看此视频:http://www.youtube.com/watch?v=hD0HAo2iHbE