女儿:爸爸,我最近迷上了翻唱,哎,只是可惜~
爸爸:可惜啥??
女儿:可惜这么好听的声音不能跟别人一起分享。
爸爸:作为麦霸还有这种苦恼?
女儿:现场唱当然没问题,但总不能想要分享的时候就拉着朋友们去K歌吧。
爸爸:也是。
女儿:所以我想要的效果是把翻唱歌曲的伴奏和我的唱音一起录制保存成CD或mp3。就像在录音棚里录歌那样。
爸爸:明白。爸爸试试给你做个recording studio。
女儿:这么厉害?期待期待!
<思路>
- 女儿收藏的mp3歌曲都是带原唱的作品,第一个要解决的问题是去原唱,转成伴音。sox里有个oops效果器可以完成这个任务。
- 接着,需要将女儿的唱音(即麦克风录音) 跟伴音做混合,存成文件。
- 这里有个唱音跟伴音同步的问题。可以在唱音路径和伴音路径上各加一个延时器,调音师通过调节这两个延时器来让唱音跟伴音同步。
- 调音师需要能够听到唱伴混合的最终效果,所以需要设计一路最终播放到调音师的耳机。
- 歌手需要只听到伴奏的声音,所以需要设计一路伴奏音播放到歌手的耳机。
<代码实现>
MyEngineerDaddy_6.cpp
#include <lark/lark.h>
#include <klogging.h>
#if defined(__APPLE__)
#define SUFIX ".dylib"
#elif defined(_WIN32)
#define SUFIX ".dll"
#else
#define SUFIX ".so"
#endif
int main()
{
const unsigned int rate = 44100;
const lark::SampleFormat format = lark::SampleFormat::S16_LE;
const unsigned int chNum = 2;
const unsigned int frameDuration_ms = 20;
const lark::samples_t frameSizeInSamples = frameDuration_ms * rate / 1000;
// Create the playback route named RouteA
lark::Route *route = lark::Lark::Instance().NewRoute("RouteA");
if (!route) {
KLOGE("Failed to create route");
return -1;
}
// Create RouteA's blocks
const char *soFileName = "libblkfilereader" SUFIX;
lark::Parameters args;
args.push_back("./original_song-44100_16_2.pcm");
lark::Block *blkFileReader = route->NewBlock(soFileName, true, false, args);
if (!blkFileReader) {
KLOGE("Failed to new a block from %s", soFileName);
return -1;
}
soFileName = "libblkformatadapter" SUFIX;
lark::Block *blkFormatAdapter0 = route->NewBlock(soFileName, false, false);
if (!blkFormatAdapter0) {
KLOGE("Failed to new a block from %s", soFileName);
return -1;
}
soFileName = "libblkformatadapter" SUFIX;
lark::Block *blkFormatAdapter1 = route->NewBlock(soFileName, false, false);
if (!blkFormatAdapter1) {
KLOGE("Failed to new a block from %s", soFileName);
return -1;
}
soFileName = "libblksoxeffect" SUFIX;
args.clear();
args.push_back("oops");
lark::Block *blkSoxOops = route->NewBlock(soFileName, false, false, args);
if (!blkSoxOops) {
KLOGE("Failed to new a block from %s", soFileName);
return -1;
}
soFileName = "libblkduplicator" SUFIX;
lark::Block *blkDuplicator1 = route->NewBlock(soFileName, false, false)