## ACM stream convert (wave compression)

Please post bug reports, feature requests, or any question regarding the DELPHI AREA projects here.

### ACM stream convert (wave compression)

I need to convert PCM data to another installed acm codec. for example PCM 8.000 kHz, 8 Bit, Mono to gsm 6.10. What is the easiest way to make this?

Sorry I couldnt find any way to convert pcm to another format in Wave Audio . But I believe that pcm to pcm converting easy.
cozturk
Moderator

Posts: 63
Joined: June 30th, 2005, 5:39 am
Location: Istanbul - Turkiye

You couldn't find the method, because probably you didn't read the document carefully.

function TWave.ConvertTo(const pTargetWaveFormat: PWaveFormatEx): Boolean;
Converts the wave audio to the specified format. If the function succeeds to convert the wave, it returns True, otherwise it returns False. For more information, please read Multistep Format Conversion on MSDN.
Kambiz

Kambiz

Posts: 2428
Joined: March 7th, 2003, 7:10 pm

Hi Kambiz,

In my voice operated recorder project after pcm wave completed and normalized it will be compressed as:

WaveStorage2.Wave.ConvertTo(...
WaveStorage2.Wave.SaveToFile(..

But if wav file is very long, my application froozen. What do you suggest? Threaded operation or another way?

While converting , all of wave stream must be loaded to memory?

Is it possible converting block by block on file stream?
cozturk
Moderator

Posts: 63
Joined: June 30th, 2005, 5:39 am
Location: Istanbul - Turkiye

Yes, you can. Use WaveUtils.ConvertWaveFormat function.
Kambiz

Kambiz

Posts: 2428
Joined: March 7th, 2003, 7:10 pm

Hi Kambiz,

This is live voice recorder and convertor project. normalize etc not included yet.

Wave data have to be recorded memory stream. and memorystream size > X.. should be compressed and added file stream.

In this sample how can use WaveUtils.ConvertWaveFormat function?

File stream must be initialized and closed acording to stream size and format.

Would you give us a small code part?

Thank you very much.
Attachments
mySound Recorder.zip
cozturk
Moderator

Posts: 63
Joined: June 30th, 2005, 5:39 am
Location: Istanbul - Turkiye

Here is a rough implementation of your describe scenario. I used your code as template.
Attachments
mySound_Recorder(fixed).zip
MySound_Recorder + Converter
Kambiz

Kambiz

Posts: 2428
Joined: March 7th, 2003, 7:10 pm

Thank you very much Kambiz. I'm happy. This site and your information very useful for me.

PS: And I want to donate some funds. How is the way for this? you said Paypal is not available for Iran. I think you have a credit card, then paypal may be ok for worldwide.
cozturk
Moderator

Posts: 63
Joined: June 30th, 2005, 5:39 am
Location: Istanbul - Turkiye

I have a PayPal account but PayPal blocks all accesses from Iran. But, there's a donation link via Shareit in top of the products page (http://delphiarea.com/products/) that you may want to use it. You'll be the first one. Thank you very much.
Kambiz

Kambiz

Posts: 2428
Joined: March 7th, 2003, 7:10 pm

Interruption occurs on the voice.
If Voice level=0 it can be ignored. (not heard)

Code: Select all
if WaveBuffer.Size >= BufferSize*10 then

if 10 increased , Interruption infrequently occurs.

Compressing needed without Interruption. May be compressed for every OnData event

Sample voice attached
Attachments
testWave.zip
cozturk
Moderator

Posts: 63
Joined: June 30th, 2005, 5:39 am
Location: Istanbul - Turkiye

1. Compression on every OnData event will improve the performance but it is not enough.
2. There is unnecessary memory allocation and data copy that can be eliminated.
I'll try to post a sample code here because seems there are many guys interested in this topic.
Kambiz

Kambiz

Posts: 2428
Joined: March 7th, 2003, 7:10 pm

For example BufferCount is 10. now 6th buffer filling by device. we can compress previosly filled 1st ..2nd.. buffers . This is already implemented Double buffering mechanism.

many guys ? I don't think. I'have checked this topic from many locations and IP adresses. some times without login. Of course but not 855 times.
cozturk
Moderator

Posts: 63
Joined: June 30th, 2005, 5:39 am
Location: Istanbul - Turkiye

Last night I wrote a sample code. I used a circular buffer and eliminated useless data transfers. Also, I gave the conversion task to a separate thread.

But all of that didn't solve the problem. I was forgotten that I've implemented ConvertWaveFormat function for converting a complete audio data, and this function is not suitable for streaming.

I will add the required functinality to the next release of the package. It will be available soon.
Kambiz

Kambiz

Posts: 2428
Joined: March 7th, 2003, 7:10 pm

I introduced a new class for wave stream conversion. In the attachment you will find the revision of the previous code that benefits from the new class.

In the new code, the recorded sound converts continuously without those noises and interruptions.
There is no need for any additional buffering, the internal buffers of the recorder component is enough.

In the new package's zip file (v1.82) you will find a more complete example.
Attachments
MySound_Recorder.zip
MySound_Recorder (using WA v1.82)
Kambiz

Kambiz

Posts: 2428
Joined: March 7th, 2003, 7:10 pm

Here is an another implementation that uses an extra circular buffer and a separate thread for conversion.

Actually always one buffer places in the circular buffer. Therefore, the circular buffer and the conversion thread are both useless.
Attachments
MySound_Recorder (using WA v1.82 + Circular Buffer + Conversion Thread)
Kambiz

Kambiz

Posts: 2428
Joined: March 7th, 2003, 7:10 pm

This is great feature!. Now we can do something on live data. not only comporessing. Voice changing, reverb.., effects may be added easily.

WaveFile.Write(Buffer^, BufferSize);

Simply before this line we can do something on PCM data and write or send as compressed!

Thank you Kambiz.
cozturk
Moderator

Posts: 63
Joined: June 30th, 2005, 5:39 am
Location: Istanbul - Turkiye

Next