gpt4 book ai didi

c# - 从 C : fputc and fwrite in C#? 转换

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:58:16 24 4
gpt4 key购买 nike

问题:为了编写一个 C# 接口(interface)到 libespeak,我需要将回调 SynthCallback 转换为 C#

参见下面的C代码。
您可能需要这个作为引用:
https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
http://www-mmsp.ece.mcgill.ca/documents/audioformats/wave/wave.html

基本上,

espeak_initialize
espeak_SetSynthCallback(SynthCallback);
espeak_SetParameter(espeakRATE, 510, 0);
espeak_Synth(".", 20, 0, POS_CHARACTER, 0, 0, NULL, NULL);

是DllImport-ed函数。我已经让它们在没有文件的情况下异步工作。

现在我想获得处理文件的同步版本,但我有一个小问题:

回调函数

static int SynthCallback(short *wav, int numsamples, espeak_EVENT *events)

首先,我需要创建一个委托(delegate),以便我可以将此函数传递给 C dll/so。这不是问题,但如果我将 short *wav 转换为 System.IntPtr,我该如何将数据写入文件?

换句话说:有人可以帮助我将 fwritefputcWrite4Bytes 转换为正确的 C#

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <espeak/speak_lib.h>

// gcc -o mine speak.cpp -I/usr/include/espeak/ -lespeak


FILE *f_wavfile = NULL;

static int SynthCallback(short *wav, int numsamples, espeak_EVENT *events);


// Write 4 bytes to a file, least significant first
static void Write4Bytes(FILE *f, int value)
{
int ix;

for(ix=0; ix<4; ix++)
{
fputc(value & 0xff,f);
value = value >> 8;
}
}



int OpenWavFile(char *path, int rate)
{
static unsigned char wave_hdr[44] = {
'R','I','F','F',0x24,0xf0,0xff,0x7f,'W','A','V','E','f','m','t',' ',
0x10,0,0,0,1,0,1,0, 9,0x3d,0,0,0x12,0x7a,0,0,
2,0,0x10,0,'d','a','t','a', 0x00,0xf0,0xff,0x7f
};


if(path == NULL)
return(2);

if(path[0] == 0)
return(0);

if(strcmp(path,"stdout")==0)
f_wavfile = stdout;
else
f_wavfile = fopen(path,"wb");

if(f_wavfile == NULL)
{
fprintf(stderr,"Can't write to: '%s'\n",path);
return(1);
}


fwrite(wave_hdr, 1, 24, f_wavfile);
Write4Bytes(f_wavfile, rate);
Write4Bytes(f_wavfile, rate * 2);
fwrite(&wave_hdr[32], 1, 12, f_wavfile);
return(0);
} // end of OpenWavFile



static void CloseWavFile()
{
unsigned int pos;

if((f_wavfile==NULL) || (f_wavfile == stdout))
return;

fflush(f_wavfile);
pos = ftell(f_wavfile);

fseek(f_wavfile, 4, SEEK_SET);
Write4Bytes(f_wavfile, pos - 8);

fseek(f_wavfile, 40, SEEK_SET);
Write4Bytes(f_wavfile, pos - 44);

fclose(f_wavfile);
} // end of CloseWavFile


int main()
{
char buf[22050];
int i = 0;
memset(&buf, 0, sizeof(buf));
// OpenWavFile((char*) "test.wav", 22050);
int SampleRate = espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS, 300, NULL, 0);

OpenWavFile((char*) "test.wav", SampleRate);

espeak_SetSynthCallback(SynthCallback);
//espeak_SetParameter(espeakRATE, 510, 0);
//espeak_SetParameter(espeakRANGE, 75, 0);
for (i=0; i < 9;i++)
{
/*
espeak_ERROR espeak_Synth(
const void *text,
size_t size,
unsigned int position,
espeak_POSITION_TYPE position_type,
unsigned int end_position,
unsigned int flags,
unsigned int* unique_identifier,
void* user_data);
*/
//espeak_POSITION_TYPE.POS_CHARACTER
espeak_Synth("test", 10, 0, POS_CHARACTER, 0, 0, NULL, NULL);
fwrite(buf, 1, 5512, f_wavfile);
espeak_Synth(".", 20, 0, POS_CHARACTER, 0, 0, NULL, NULL);
fwrite(buf, 1, 22050, f_wavfile);
}
CloseWavFile();
}


static int SynthCallback(short *wav, int numsamples, espeak_EVENT *events)
{
if (wav == NULL)
return 0;

if (numsamples > 0)
{
fwrite(wav, numsamples * 2, 1, f_wavfile);
}

return 0;
}

最佳答案

FileStream sink;
Int32 SynthCallback(IntPtr wav, Int32 numsamples, IntPtr events)
{
var wavm = new Int16[numsamples];
Marshal.Copy(wav, wavm, 0, numsamples);
// and do something with wavm

//or
var wavbytes = new Byte[numsamples * 2];
Marshal.Copy(wav, wavbytes, 0, numsamples*2);
sink.Write(wavbytes, 0, numsamples*2);
}

要写入 32 位整数,您可以使用 BitConverter.GetBytesFileStream.Write 或者 BinaryWriter

关于c# - 从 C : fputc and fwrite in C#? 转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6563764/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com