I need to find a better way to record an audio stream. I already created low-level C ++ code and paired it with C #.
So, I have a C ++ callback that gives me an array of float arrays - an audio signal. At the moment, my C ++ lib writes data directly to a wav file, and it just notifies my C # application when it finishes writing.
But I would like to have more interactivity on the user interface side, for example, an โendlessโ progress bar, the amount of recorded data, the cancel button, etc., and since in the worst case it will be a minute, it might be better to store it in memory. I know very little about memory management in .NET and C #, so I donโt know how to do this efficiently.
Is there any quick resizable container in C # where I could just put the data inside and later get it as an array?
I would also like to create a waveform image. I already did this in C ++, but somehow I donโt like the idea of โโwriting too many messages, passing objects, etc.
So, to put things together:
I have an unmanaged C ++ callback that does some things, and from the inside I would like to call the C # method, as soon as it processes the data, the C prototype would be:
void process (float ** signal, int n); (usually [2] [n] - for stereo)
What is the C # equivalent and how can I call it from this C ++ callback?
(,
mem.put(float [] [] data, int size)),
(, wav
)
, #? ( ++-, # .. , , DSP), ?:)
,
pablox
, :
++ :
public ref struct CVAudio {
public:
float *left;
float *right;
int length;
};
++ :
delegate void GetAudioData([In, Out] CVAudio^ audio);
, :
void initializeSoundSystem(void *HWnd, GetAudioData ^audio);
C
typedef void (CALLBACK *GETAUDIODATA)(CVAudio ^a);
++ :
void initializeSoundSystem(HWND HWnd, GETAUDIODATA audio);
:
void VDAudio::initializeSoundSystem(void *HWnd, GetAudioData ^audio)
{
HWND h = (HWND) HWnd;
acb = audio;
pin_ptr<GetAudioData ^> tmp = &audio;
IntPtr ip = Marshal::GetFunctionPointerForDelegate(audio);
GETAUDIODATA cb = static_cast<GETAUDIODATA>(ip.ToPointer());
audioObserver->initializeSoundSystem(h, cb);
}
.
:
VDAudio^ a = gcnew VDAudio();
a->left = VHOST->Master->getSample()[0];
a->right = VHOST->Master->getSample()[1];
a->length = length;
(*callback)(a);
#:
public void GetSamples(CVAudio audio)
{
unsafe
{
float* l = (float*)audio.left;
float* r = (float*)audio.right;
if (l != null)
{
SamplePack sample = new SamplePack();
sample.left = new float[audio.length];
sample.right = new float[audio.length];
IntPtr lptr = new IntPtr((void*)l);
IntPtr rptr = new IntPtr((void*)r);
Marshal.Copy(lptr, sample.left, 0, audio.length);
Marshal.Copy(rptr, sample.right, 0, audio.length);
this.Dispatcher.Invoke(new Action(delegate()
{
GetSamples(sample);
}));
}
}
}
, , - . , , , ..:)