如何以编程方式在 Android 中将 .mid 转换为 .wav 文件?

Posted

技术标签:

【中文标题】如何以编程方式在 Android 中将 .mid 转换为 .wav 文件?【英文标题】:How to convert .mid to .wav file in Android programmatically? 【发布时间】:2021-07-15 18:44:32 【问题描述】:

我想允许用户在我的 android 应用中将 .mid 文件转换为 .wav 文件。

实际上,网络上没有太多关于任何类型的 midi 到 wav 转换的信息,因此在 Android 中进行这种转换的信息非常少。

我该怎么办?去哪儿?

【问题讨论】:

这个问题和答案是针对特定图书馆的某种垃圾邮件。 您所说的“针对特定图书馆的垃圾邮件”是什么意思? @javdromero 【参考方案1】:

TL;DR

与您选择的此答案中的特色方式无关,您必须在项目中包含一些 c 代码。而且您还必须包含在 LGPL-2.1 下许可的 lib。你真的应该注意这两个。阅读this 以更好地理解它。真的。请阅读它。理解这一点很重要。

惰性选项 - 使用 my lib

更好的选择 - 按照任一链接(official github page guide 和\或Medium article)设置 FluidSynth,将 this snippet of code 包含到您的项目中,一切顺利。此代码应包含在您的项目中,就像上面列出的 Medium 文章中所解释的那样。

非常糟糕的选择 - 使用 Timidity++。

更详细的版本

转换中间文件时有两个选项:FluidSynth 和 Timidity++。我不建议您使用 Timidity++ 将 .mid 转换为原始音频。该库有点旧,不受支持;找不到文档和社区。 FluidSynth 是一个更好的选择:它更新,支持,它有大量的 API 文档,它的社区比 Timidity 的更活跃。我无法让 Timidity 在 Android 上运行。

无论如何,如果您想使用 Timidity,这里有一些链接。

somewhat usable timidity lib example of converting mid to wav a working app featuring timidity(我无法在这段代码中得到任何东西,但这个应用程序使用胆小,它能够将 mid 转换为 wav,这是事实) 这不是胆怯资源的完整列表。此外,网络上有一些神秘的 repos 声称是胆怯或某种胆怯 lib 甚至是 android 的 lib……但我个人从来不明白那里发生了什么,所以我不推荐胆小怕事。

惰性选项

最懒惰的选择是使用my own library。所有说明都在 Github 自述文件中。可能不建议使用我的 lib,因为我的实现可能存在一些大的性能问题。

您可以在 lib 的自述文件中查看使用此方法的示例。

更好的选择

将 .mid 转换为 .wav 文件的最佳选择是使用FluidSynth 软件合成器。这样你就必须做一些 c 编码。我告诉过你。

官方 github wiki 获得了有关如何为 Android 设置 FluidSynth 的 instruction,但我建议您阅读 this Medium article 来了解如何配置此合成器,因为它更容易理解和理解。

设置完之后,您可以进行一些简洁的 .mid 到 .wav 的转换。这是the official docs。将代码留在此处以防链接失效。

    fluid_settings_t* settings;
    fluid_synth_t* synth;
    fluid_player_t* player;
    fluid_file_renderer_t* renderer;

    settings = new_fluid_settings();

    // specify the file to store the audio to
    // make sure you compiled fluidsynth with libsndfile to get a real wave file
    // otherwise this file will only contain raw s16 stereo PCM
    fluid_settings_setstr(settings, "audio.file.name", "/path/to/output.wav");
    // use number of samples processed as timing source, rather than the system timer
    fluid_settings_setstr(settings, "player.timing-source", "sample");

    // since this is a non-realtime scenario, there is no need to pin the sample data
    fluid_settings_setint(settings, "synth.lock-memory", 0);
    synth = new_fluid_synth(settings);
    // *** loading of a soundfont omitted ***

    player = new_fluid_player(synth);
    fluid_player_add(player, "/path/to/midifile.mid");
    fluid_player_play(player);
    renderer = new_fluid_file_renderer (synth);
    while (fluid_player_get_status(player) == FLUID_PLAYER_PLAYING)
    
        if (fluid_file_renderer_process_block(renderer) != FLUID_OK)
        
            break;
        
    

    // just for sure: stop the playback explicitly and wait until finished
    fluid_player_stop(player);
    fluid_player_join(player);
    delete_fluid_file_renderer(renderer);
    delete_fluid_player(player);
    delete_fluid_synth(synth);
    delete_fluid_settings(settings);

...基本上就是这样。您现在可以开始将 .mid 转换为 .wav 文件了。

Here 是有关如何将该代码集成到您的项目中的示例。

Here 是如何在您的 android 代码中使用此功能的示例。

【讨论】:

以上是关于如何以编程方式在 Android 中将 .mid 转换为 .wav 文件?的主要内容,如果未能解决你的问题,请参考以下文章

在其线性布局垂直父Android中将以编程方式创建的单选按钮居中

Android:以编程方式覆盖 Button minheight

如何在 Android 中将子视图添加到 ImageView

如何以编程方式在 iphone 中将音乐文件设置为通话音和消息音

如何在 iPhone 上以编程方式在 Swift 中将 UIViewController 呈现为弹出框

如何以编程方式在 Swift 中将 uiimageview 设置为 xcode 内置的 applewatch 图标图像?