Hello Fre;D
Help me please! I work with digital sound processing on Lazarus because I have old units written on Pascal and Object Pascal. Now I need open WAV file then take buffer from it and process this buffer. Then I need save in new WAV file that has processed buffer. But I can not save the buffer in WAV file with parameters of opened file. Specifically I have such parameters in open WAV file thebufferinfos.SampleRate = 44100 thebufferinfos.SampleRateRoot = 44100 thebufferinfos.SampleFormat = 0 thebufferinfos.Channels = 1 thebufferinfos.Genre = 0 thebufferinfos.HDFormat = 65538 thebufferinfos.Sections = 1 thebufferinfos.Encoding = -1 thebufferinfos.bitrate = -1 thebufferinfos.Length = 61911 thebufferinfos.LibOpen = 0 thebufferinfos.Ratio = 2 but I can not set this parameters for the file I like to save. When I perform the route PlayerIndex1 := 0; uos_CreatePlayer(PlayerIndex1); InputIndex1 := uos_AddFromMemoryBuffer(PlayerIndex1,thebuffer,thebufferinfos, -1, -1); if InputIndex1 > -1 then begin uos_EndProc(PlayerIndex1, @ClosePlayer); OutputIndex1 := uos_addIntoFileFromMem(PlayerIndex1, Pchar('/home/user/MyWav.wav'),-1,1,-1,-1,1 ); if OutputIndex1 > -1 then begin uos_Play(PlayerIndex1); end; end; I get WAV file with such parameters thebufferinfos.SampleRate = 44100 thebufferinfos.SampleRateRoot = 44100 thebufferinfos.SampleFormat = 0 thebufferinfos.Channels = 1 thebufferinfos.Genre = 0 thebufferinfos.HDFormat = 65538 thebufferinfos.Sections = 1 thebufferinfos.Encoding = -1 thebufferinfos.bitrate = -1 thebufferinfos.Length = 30955 thebufferinfos.LibOpen = 0 thebufferinfos.Ratio = 2 What do I do wrong? Thanks for an answer. |
Administrator
|
Hello.
AddintofileFromMem() is used for memory streams (<> memory buffer). Using Addintofile() does not work for you ?): PlayerIndex1 := 0; uos_CreatePlayer(PlayerIndex1); InputIndex1 := uos_AddFromMemoryBuffer(PlayerIndex1,thebuffer,thebufferinfos, -1, -1); if InputIndex1 > -1 then begin uos_EndProc(PlayerIndex1, @ClosePlayer); OutputIndex1 := uos_addIntoFile(PlayerIndex1, Pchar('/home/user/MyWav.wav') ); // here change if OutputIndex1 > -1 then begin uos_Play(PlayerIndex1); end; end; function uos_AddIntoFile(PlayerIndex: cint32; Filename: PChar): cint32; // Add a Output into audio wav file with Default parameters // PlayerIndex : Index of a existing Player // FileName : filename of saved audio wav file function uos_AddIntoFile(PlayerIndex: cint32; Filename: PChar; SampleRate: cint32; Channels: cint32; SampleFormat: cint32 ; FramesCount: cint32 ; FileFormat: cint32): cint32; // Add a Output into audio wav file with custom parameters // PlayerIndex : Index of a existing Player // FileName : filename of saved audio wav file // SampleRate : delault : -1 (44100) // Channels : delault : -1 (2:stereo) (1:mono, 2:stereo, ...) // SampleFormat : default : -1 (2:Int16) (1:Int32, 2:Int16) // FramesCount : default : -1 (= 65536) // FileFormat : default : -1 (wav) (0:wav, 1:pcm, 2:custom); // result :Output Index in array -1 = error |
Administrator
|
Re-hello.
Maybe you will need to use Addintofile(...) with custom parameters, according your buffer setup. Fre;D |
Administrator
|
Re-re hello.
I see that you are using for the buffer: thebufferinfos.SampleFormat = 0 (float resolution) Wav file format usually uses integer (thebufferinfos.SampleFormat := 2 (or 1); I did not test but maybe others applications can read wav files with float samples. I fear that you will need to explore with different resolutions to get what you want. Fre;D |
Re-hello Fre;D!
Thanks for the answer. I use thebufferinfos.SampleFormat = 0 because I get real value when I have opened wav file with this parameter. I open wav file with that time dependence (wav file opened in Audacity) by the next route Res := uos_LoadLib(Pchar(PA_FileName), Pchar(SF_FileName), pchar(MP_FileName), nil, nil, nil) ; If Res=0 Then thebuffer := uos_File2Buffer(pchar(SoundFilename), 0, thebufferinfos, -1, -1); I get the next time dependence of sound sygnal But if I save that buffer in wav file by route PlayerIndex1 := 0; uos_CreatePlayer(PlayerIndex1); InputIndex1 := uos_AddFromMemoryBuffer(PlayerIndex1,thebuffer,thebufferinfos, -1, -1); if InputIndex1 > -1 then begin uos_EndProc(PlayerIndex1, @ClosePlayer); OutputIndex1 := uos_addIntoFile(PlayerIndex1, Pchar('/home/user/MyWav.wav'), -1,1,1,-1,1 ); // if OutputIndex1 > -1 then uos_Play(PlayerIndex1); end; I get the next time dependence Then I opened wav file with thebufferinfos.SampleFormat = 1 by the route Res := uos_LoadLib(Pchar(PA_FileName), Pchar(SF_FileName), pchar(MP_FileName), nil, nil, nil) ; If Res=0 Then thebuffer := uos_File2Buffer(pchar(SoundFilename), 1, thebufferinfos, -1, -1); I get the next time dependence of sound sygnal But after saving buffer by standard route I get such time dependence Note! The signal saves timbre voice but is two times shorter! When I opened wav file with thebufferinfos.SampleFormat = 2 by the route Res := uos_LoadLib(Pchar(PA_FileName), Pchar(SF_FileName), pchar(MP_FileName), nil, nil, nil) ; If Res=0 Then thebuffer := uos_File2Buffer(pchar(SoundFilename), 2, thebufferinfos, -1, -1); I get the next time dependence of sound signal But after saving buffer by standard route I get such time dependence Does it mean that I shoud open wav file with one value SampleFormat and save it with an other value? How to find parameters for opening and saving buffer in wave file of 16 bit? Maybe I'd better work with other sound formats to use UOS? Thanks for the answer. |
Administrator
|
In reply to this post by Dan Mistrenko
Hello.
Did you try the demo /uos/SimpleRecorder.lpi ? Is it working when you save it ? What is your OS (Linux, Windows? Raspbian, FreeBSD, ...) ? When creating the buffer what kind of file is SoundFilename? thebuffer := uos_File2Buffer(pchar(SoundFilename), 0, thebufferinfos, -1, -1); > How to find parameters for opening and saving buffer in wave file of 16 bit? Please read my previous post: function uos_AddIntoFile(PlayerIndex: cint32; Filename: PChar; SampleRate: cint32; Channels: cint32; SampleFormat: cint32 ; FramesCount: cint32 ; FileFormat: cint32): cint32; // Add a Output into audio wav file with custom parameters from TFileStream // PlayerIndex : Index of a existing Player // FileName : filename of saved audio wav file // SampleRate : delault : -1 (44100) // Channels : delault : -1 (2:stereo) (1:mono, 2:stereo, ...) // SampleFormat : default : -1 (2:Int16) (1:Int32, 2:Int16) // FramesCount : default : -1 (= 65536) // FileFormat : default : -1 (wav) (0:wav, 1:pcm, 2:custom); // result :Output Index in array -1 = error function uos_File2Buffer(Filename: Pchar; SampleFormat: cint32 ; var bufferinfos: Tuos_BufferInfos ; frompos : cint; numbuf : cint ): TDArFloat; // Create a memory buffer of a audio file. // FileName : filename of audio file // SampleFormat : default : -1 (1:Int16) (0: Float32, 1:Int32, 2:Int16) // bufferinfos : the infos of the buffer. // frompos : from position (default : -1 = from begining, otherwise position in song) // numbuf : number of frames to add to outmemory (default : -1 = all, otherwise number max of frames) // result : The memory buffer > Maybe I'd better work with other sound formats to use UOS? What sound format are you using? It would be much easier for me to help you if you give a complete code of what you want to do. Fre;D |
Administrator
|
In reply to this post by fredvs
Re-hello.
Could you please take a look at /uos/consoleplaymemorybuffer.lpi demo? Here the code adapted to save to file, I get a wav file correct (see attachment): MyWav.wav .... ordir := IncludeTrailingBackslash(ExtractFilePath(ParamStr(0))); SoundFilename := ordir + 'sound/test.wav'; res := uos_LoadLib(Pchar(PA_FileName), Pchar(SF_FileName), nil, nil, nil, nil) ; writeln('Result of loading (if 0 => ok ) : ' + IntToStr(res)); if res = 0 then begin PlayerIndex1 := 0; // Create a memory buffer from a audio file thebuffer := uos_File2Buffer(pchar(SoundFilename), 1, thebufferinfos, -1, -1); // You may store that buffer into ressource... // ... and when you get the buffer from ressource.... uos_CreatePlayer(PlayerIndex1); // Add a input from memory buffer with custom parameters input1 := uos_AddFromMemoryBuffer(PlayerIndex1,thebuffer,thebufferinfos, -1, 1024); // here add into file: uos_addIntoFile(PlayerIndex1, Pchar('/home/fred/MyWav.wav'), -1,1,1,-1,1 ); // // everything is ready, here we are, lets play it... uos_Play(PlayerIndex1); sleep(2000); end; end; |
Administrator
|
Re-hello.
If I know exactly what you want to achieve, it would be great. Why do you need to convert the wav file into buffer? You may also use uos_AddFromMemoryStream(), please take a look at demo /uos/consoleplaymemorystream.lpi. Fre;D |
Hello Fre;D
Thanks for the answer. I work in Xubuntu 16.04, Lazarus 2.0.2 or 2.0.10. I studied the codes consoleplaymemorybuffer.lpi but if I work on graphical environment SampleFormat works differently. I want to understand where is a mistake. Here is my project: sonar_201109.lpi sonar_201109.lpr unit1.pas unit1.lfm Unit_Kernel.pas Here wav file to transform Mimo_Kat_44100kH_16bit_001.wav I work with open source cross-platform project on Lazarus for speech processing. Then I need get access to transform buffer for saving it in different files. |
Administrator
|
This post was updated on .
Hello.
Ok, I think I get it. There was indeed a problem with SaveToFile if the buffer is mono. Thanks to note it. It was fixed on last commit of uos: This code, adapted from the consoleplaybuffer demo works for me: But you need last commit of uos. SoundFilename := '/home/fred/Downloads/Mimo_Kat_44100kH_16bit_001.wav'; PlayerIndex1 := 0; // Create a memory buffer from a audio file thebuffer := uos_File2Buffer(pchar(SoundFilename), 1, thebufferinfos, -1, -1); uos_CreatePlayer(PlayerIndex1); // Add a input from memory buffer with custom parameters input1 := uos_AddFromMemoryBuffer(PlayerIndex1,thebuffer,thebufferinfos, -1, 1024); // add a Output into device with default parameters {$if defined(cpuarm)} // needs lower latency uos_AddIntoDevOut(PlayerIndex1, -1, 0,3, uos_inputgetSampleRate(PlayerIndex1,input1), uos_inputgetChannels(PlayerIndex1,input1) , 0, 1024, -1); {$else} uos_AddIntoDevOut(PlayerIndex1, -1, -1, uos_inputgetSampleRate(PlayerIndex1,input1), uos_inputgetChannels(PlayerIndex1,input1) , 0, 1024, -1); {$endif} // Add into file uos_addIntoFile(PlayerIndex1, Pchar('/home/fred/testwav.wav'), -1,1,1,1024,-1 ); /////// everything is ready, here we are, lets play it... uos_Play(PlayerIndex1); sleep(2000); end; I hope it will solve your problems, otherwise, dont hesitate to say it. Fre;D [EDIT] Included the result of the saved file from Mimo_Kat_44100kH_16bit_001.wav testwav.wav |
Administrator
|
This post was updated on .
Re-hello.
The previous demo saves the buffers in wav file with 32 bit format. If you want a wav 16 bit, this works here too (note the format param set to 2 = integer 16 bit): SoundFilename := '/home/fred/Downloads/Mimo_Kat_44100kH_16bit_001.wav'; // Create a memory buffer from a audio file thebuffer := uos_File2Buffer(pchar(SoundFilename), 2, thebufferinfos, -1, -1); // You may store that buffer into ressource... // ... and when you get the buffer from ressource.... uos_CreatePlayer(PlayerIndex1); // Add a input from memory buffer with custom parameters input1 := uos_AddFromMemoryBuffer(PlayerIndex1,thebuffer,thebufferinfos, -1, 1024); // add a Output into device with default parameters {$if defined(cpuarm)} // needs lower latency uos_AddIntoDevOut(PlayerIndex1, -1, 0,3, uos_inputgetSampleRate(PlayerIndex1,input1), uos_inputgetChannels(PlayerIndex1,input1) , 2, 1024, -1); {$else} uos_AddIntoDevOut(PlayerIndex1, -1, -1, uos_inputgetSampleRate(PlayerIndex1,input1), uos_inputgetChannels(PlayerIndex1,input1) , 2, 1024, -1); {$endif} // { // Save to file uos_addIntoFile(PlayerIndex1, Pchar(ordir + 'testwav16.wav'), uos_inputgetSampleRate(PlayerIndex1,input1), uos_inputgetChannels(PlayerIndex1,input1),-1,1024,-1 ); // // } /////// everything is ready, here we are, lets play it... uos_Play(PlayerIndex1); sleep(2000); end; ///// Here testwav16.wav result: testwav16.wav |
Free forum by Nabble | Edit this page |