使用C中的libFLAC将WAV转换为FLAC#
我尝试将端口移植到C#,并得出以下代码:使用C中的libFLAC将WAV转换为FLAC#,c#,pinvoke,flac,C#,Pinvoke,Flac,我尝试将端口移植到C#,并得出以下代码: public class LibFLAC { public static void Test() { string inputPath = Path.Combine("D:\\", "_", "test.pcm"); string outputPath = Path.Combine("D:\\", "_", "test.flac"); uint channels = 2; uin
public class LibFLAC {
public static void Test() {
string inputPath = Path.Combine("D:\\", "_", "test.pcm");
string outputPath = Path.Combine("D:\\", "_", "test.flac");
uint channels = 2;
uint bitsPerSample = 16;
uint sampleRate = 44100;
IntPtr encoder = FLAC__stream_encoder_new();
if (encoder == IntPtr.Zero) throw new Exception("Encoder: NEW failed");
bool ok = true;
ok &= FLAC__stream_encoder_set_channels(encoder, channels);
ok &= FLAC__stream_encoder_set_bits_per_sample(encoder, bitsPerSample);
ok &= FLAC__stream_encoder_set_sample_rate(encoder, sampleRate);
ok &= FLAC__stream_encoder_set_compression_level(encoder, 5);
// ok &= FLAC__stream_encoder_set_verify(encoder, true);
if (!ok) throw new Exception("Encoder: SET failed");
int status = FLAC__stream_encoder_init_file(encoder, outputPath, IntPtr.Zero, IntPtr.Zero);
if (status != 0) throw new Exception("Encoder: INIT FILE failed");
using (FileStream stream = new FileStream(inputPath, FileMode.Open, FileAccess.Read)) {
uint bps = bitsPerSample / 8;
byte[] buffer = new byte[channels * bps * 1024];
Int32[] pcm = new Int32[channels * 1024];
int read;
while ((read = stream.Read(buffer, 0, buffer.Length)) != 0) {
for (var i = 0; i < read / bps; i++) {
pcm[i] = (Int32) (((uint) buffer[i * 2 + 1] << 8) | (uint) buffer[i * 2]);
}
ok = FLAC__stream_encoder_process_interleaved(encoder, pcm, (uint) (read / bps / channels));
if (!ok) throw new Exception("Encoder: PROCESS INTERLEAVED failed ::: " + FLAC__stream_encoder_get_state(encoder) + " ::: " + FLAC__stream_encoder_get_verify_decoder_state(encoder));
}
ok = FLAC__stream_encoder_finish(encoder);
if (!ok) throw new Exception("Encoder: FINISH failed");
FLAC__stream_encoder_delete(encoder);
encoder = IntPtr.Zero;
}
Console.WriteLine("\n\n\nDone");
Console.ReadKey();
}
[DllImport("libFLAC", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr FLAC__stream_encoder_new();
[DllImport("libFLAC", CallingConvention = CallingConvention.Cdecl)]
public static extern void FLAC__stream_encoder_delete(IntPtr encoder);
[DllImport("libFLAC", CallingConvention=CallingConvention.Cdecl)]
public static extern bool FLAC__stream_encoder_set_verify(IntPtr encoder, bool value);
[DllImport("libFLAC", CallingConvention = CallingConvention.Cdecl)]
public static extern bool FLAC__stream_encoder_set_channels(IntPtr encoder, uint value);
[DllImport("libFLAC", CallingConvention = CallingConvention.Cdecl)]
public static extern bool FLAC__stream_encoder_set_bits_per_sample(IntPtr encoder, uint value);
[DllImport("libFLAC", CallingConvention = CallingConvention.Cdecl)]
public static extern bool FLAC__stream_encoder_set_sample_rate(IntPtr encoder, uint value);
[DllImport("libFLAC", CallingConvention = CallingConvention.Cdecl)]
public static extern bool FLAC__stream_encoder_set_compression_level(IntPtr encoder, uint value);
[DllImport("libFLAC", CallingConvention = CallingConvention.Cdecl)]
public static extern int FLAC__stream_encoder_init_file(IntPtr encoder, string filename, IntPtr progress_callback, IntPtr client_data);
[DllImport("libFLAC", CallingConvention = CallingConvention.Cdecl)]
public static extern bool FLAC__stream_encoder_process_interleaved(IntPtr encoder, Int32[] buffer, uint samples);
[DllImport("libFLAC", CallingConvention = CallingConvention.Cdecl)]
public static extern bool FLAC__stream_encoder_finish(IntPtr encoder);
[DllImport("libFLAC", CallingConvention = CallingConvention.Cdecl)]
public static extern int FLAC__stream_encoder_get_state(IntPtr encoder);
[DllImport("libFLAC", CallingConvention = CallingConvention.Cdecl)]
public static extern int FLAC__stream_encoder_get_verify_decoder_state(IntPtr encoder);
}
公共类LibFLAC{
公共静态无效测试(){
字符串inputPath=Path.Combine(“D:\\”、“\\”、“\”、“test.pcm”);
字符串outputPath=Path.Combine(“D:\\”、“\\”、“\\”、“test.flac”);
uint通道=2;
uint位样本=16;
uint采样器=44100;
IntPtr编码器=FLAC__流_编码器_新();
if(encoder==IntPtr.Zero)抛出新异常(“encoder:new failed”);
bool ok=true;
ok&=FLAC\uuuu流\u编码器\u设置\u通道(编码器,通道);
ok&=FLAC\uuuu流\u编码器\u设置\u位\u每个样本(编码器,位样本);
ok&=FLAC\uuuu流\u编码器\u设置\u采样率(编码器、采样器);
ok&=FLAC\uuuu流\u编码器\u设置\u压缩\u级别(编码器,5);
//ok&=FLAC\uuuu流\u编码器\u设置\u验证(编码器,真);
如果(!ok)抛出新异常(“编码器:设置失败”);
int status=FLAC\uuuu stream\u encoder\u init\u文件(encoder,outputPath,IntPtr.Zero,IntPtr.Zero);
如果(状态!=0)抛出新异常(“编码器:初始化文件失败”);
使用(FileStream stream=newfilestream(inputPath,FileMode.Open,FileAccess.Read)){
uint bps=位采样/8;
字节[]缓冲区=新字节[通道*bps*1024];
Int32[]pcm=新的Int32[通道*1024];
int-read;
while((read=stream.read(buffer,0,buffer.Length))!=0){
对于(变量i=0;i
此外,如果我启用FLAC\uu流\u编码器\u设置\u验证
,程序将立即在FLAC\uu流\u编码器\u进程与
FLAC_uustreamncoderstate=4
(验证音频数据中的不匹配-验证解码器检测到原始音频信号和解码音频信号之间不匹配。)以及
FLAC\uu StreamDecoderState=3
(读取帧-解码器已准备好或正在读取帧。)
这毫无意义
我是否在转换过程中遗漏了什么或犯了错误?您的ok&=..风格不好。您需要检查每个返回值,并在其中一个失败时立即退出。@DavidHeffernan好的,我不会在主代码中这样做。如果转换成功,这只是一个快速测试。