public ref class LameWrapper sealed
{
public:
LameWrapper();
IAsyncOperation^ EncodePcm2Mp3(IBuffer^ inPcm, int sampleRate, int channels);
};
然后是用作返回值的CompressedMp3Content类的定义
public ref class CompressedMp3Content sealed
{
public:
CompressedMp3Content(void);
property Platform::Array^ Mp3Data;
};
接下来是压缩MP3的重头戏~LameWrapper.CPP
首先Include “Lame.h”
然后来看一下EncodePcm2Mp3方法:
Windows::Foundation::IAsyncOperation^ LameWrapper::EncodePcm2Mp3(IBuffer^ inPcm, int sampleRate, int channels)
{
lame_global_flags* lame = lame_init();
lame_set_in_samplerate(lame, sampleRate);
lame_set_num_channels(lame, channels);
lame_set_quality(lame, 5);
lame_init_params(lame);
IUnknown* pUnk = reinterpret_cast(inPcm);
IBufferByteAccess* pAccess = NULL;
byte* bytes = NULL;
HRESULT hr = pUnk->QueryInterface(__uuidof(IBufferByteAccess), (void**)&pAccess);
if (SUCCEEDED(hr))
{
hr = pAccess->Buffer(&bytes);
if (SUCCEEDED(hr))
{
return Concurrency::create_async([=]()->CompressedMp3Content^
{
CompressedMp3Content^ result = ref new CompressedMp3Content();
int pcmLength = inPcm->Length;
///TODO:此处直接获取了pcmLength的一半,在pcmLength为奇数的时候会丢掉最后一个字节~不过无所谓了......
std::vector inBuffer = std::vector(pcmLength / 2);
for (std::vector::size_type i=0; i 0)
{
result->Mp3Data = ref new Platform::Array(size);
for(int i=0; iMp3Data)->get(i) = outBuffer;
}
}
lame_close(lame);
pAccess->Release();
return result;
});
}
else
{
lame_close(lame);
pAccess->Release();
throw ref new Platform::Exception(hr, L"Couldn't get bytes from the buffer");
}
}
else
{
lame_close(lame);
throw ref new Platform::Exception(hr, L"Couldn't access the buffer");
}
}
先设置所需参数,通常我们录下来只有一个声道了,所以channels给个1好了,当然左右声道都给同一个PCM buffer就变成双声道了也可以,lame_set_quality时有0~9个阶段的质量可选,取中就好,设的太高压缩会很慢,接下来开始process传进来的buffer,为了方便我们给进来的是byte数组,而lame要的是short数组,所以我们要先将byte*转换为short*转换完成之后直接调用lame_encode_buffer来进行转换吧,转换完成后会返回实际的字节数,然后我们将转好的byte*放入CompressedMp3Content类中以供c#进行进一步处理,然后记得release all~~~~~
回到c#这一侧,当然要引用我们的audio工程,在C#这一侧我们先要拿到pcm流,不知道为什么使用之前提到的AudioVideoCaptureDevice录制PCM会崩溃,所以我们还是使用传统的xna下的Microphone来录制pcm流,
录制完成后就很简单了new出一个LameWrapper后直接调用EncodePCM2Mp3就好了~