This post was updated on .
Hello to the forum i made a new demo for uos that can record in MP3 and OGG/vorbis using libsndfile library with quality settings
https://trim.uk.to/my-simple-recorder.zip The mp3 recording is only VBR. I could not make CBR AVR possible the command SFC_SET_BITRATE_MODE seems to not work but SFC_SET_VBR_ENCODING_QUALITY SFC_SET_COMPRESSION_LEVEL work for both OGG and MP3 ********************** The new function added function Tuos_Player.AddIntoFile (Filenamepath: PChar; SampleRate: CDouble; Channels: cint32; SampleFormat: cint32; FramesCount: cint32; FileFormat: cint32; vbr_encoding_quality:ctypes.cdouble; compression_level:ctypes.cdouble): cint32; // Add an Output into audio wav file with custom parameters // FileName : filename of saved audio wav file // SampleRate : default: -1 (44100) // Channels : default: -1 (2:stereo) (0: no channels, 1:mono, 2:stereo, ...) // SampleFormat : default: -1 (2:Int16) ( 1:Int32, 2:Int16) // FramesCount : default: -1 (= 4096) // FileFormat : default: -1 (wav) (0:wav, 1:pcm, 2:custom, 3:ogg, 4:mp3); //vbr_encoding_quality:ctypes.cdouble ; c //compression_level:ctypes.cdouble // result : Output Index in array -1 = error // example : OutputIndex1 := AddIntoFile (edit5.Text,-1,-1, 0, -1, -1); var x: cint32; wChunkSize: cint32; wFileSize: cint32; IDwav: array[0..3] of char; Header: Tuos_WaveHeaderChunk; {$IF DEFINED (sndfile)} sfInfo: TSF_INFO; {$endif} //TrustFm bitrate_mode: ctypes.cint; res_sf_command: ctypes.cint; begin result := -1; x := 0; SetLength (StreamOut, Length (StreamOut) + 1); StreamOut[Length (StreamOut) - 1] := Tuos_OutStream.Create (); x := Length (StreamOut) - 1; StreamOut[x].Data.Enabled := false; StreamOut[x].FileBuffer.ERROR := 0; StreamOut[x].Data.Filename := filenamepath; if (FileFormat = -1) or (FileFormat = 0) then StreamOut[x].FileBuffer.FileFormat := 0 else StreamOut[x].FileBuffer.FileFormat := FileFormat; FillChar (StreamOut[x].FileBuffer, sizeof (StreamOut[x].FileBuffer), 0); result := x; if (Channels = -1) then StreamOut[x].FileBuffer.wChannels := 2 else StreamOut[x].FileBuffer.wChannels := Channels; StreamOut[x].Data.Channels := StreamOut[x].FileBuffer.wChannels; if FramesCount = -1 then StreamOut[x].Data.Wantframes := 65536 Div StreamOut[x].Data.Channels else StreamOut[x].Data.Wantframes := FramesCount; SetLength (StreamOut[x].Data.Buffer, StreamOut[x].Data.Wantframes*StreamOut[x].Data.Channels); if (SampleFormat = -1) or (SampleFormat = 2) then begin StreamOut[x].FileBuffer.wBitsPerSample := 16; StreamOut[x].Data.SampleFormat := 2; end; if (SampleFormat = 1) then begin StreamOut[x].FileBuffer.wBitsPerSample := 32; StreamOut[x].Data.SampleFormat := 1; end; if (SampleFormat = 0) then begin StreamOut[x].FileBuffer.wBitsPerSample := 32; StreamOut[x].Data.SampleFormat := 0; end; if SampleRate = -1 then StreamOut[x].FileBuffer.wSamplesPerSec := 44100 //8000 11025 16000 22050 was 44100 else StreamOut[x].FileBuffer.wSamplesPerSec := roundmath (samplerate); StreamOut[x].Data.Samplerate := StreamOut[x].FileBuffer.wSamplesPerSec; StreamOut[x].LoopProc := Nil; if fileformat = 3 then begin // ogg file {$IF DEFINED (sndfile)} StreamOut[x].FileBuffer.FileFormat := 3; StreamOut[x].Data.TypePut := 6; sfInfo.format := SF_FORMAT_OGG Or SF_FORMAT_VORBIS; //SF_FORMAT_OGG Or SF_FORMAT_VORBIS; sfInfo.channels := StreamOut[x].Data.Channels; sfInfo.frames := streamOut[x].Data.Wantframes; sfinfo.samplerate := StreamOut[x].FileBuffer.wSamplesPerSec; sfinfo.seekable := 0; //seekable was 0 StreamOut[x].Data.Enabled := true; StreamOut[x].Data.HandleSt := sf_open (pchar(FileNamepath), SFM_WRITE, sfInfo); //TrustFm //https://github.com/libsndfile/libsndfile/issues/788 //Set the Variable Bit Rate encoding quality. //The encoding quality value should be between 0.0 (lowest quality) and 1.0 (highest quality). //Currently this command is only implemented for FLAC and Ogg/Vorbis files. //It has no effect on un-compressed file formats. //vbr_encoding_quality:=0.1; res_sf_command:=-1; res_sf_command := sf_command_pointer(StreamOut[x].Data.HandleSt, SFC_SET_VBR_ENCODING_QUALITY, @vbr_encoding_quality, sizeof(vbr_encoding_quality) ); if res_sf_command = SF_TRUE then begin // compression_level:=1.0; end else if res_sf_command = SF_FALSE then begin // compression_level:=1.0; end; //Set the compression level. //The compression level should be between 0.0 (minimum compression level) and 1.0 (highest compression level). //Currently this command is only implemented for FLAC and Ogg/Vorbis files. //It has no effect on uncompressed file formats. //compression_level:=1.0; { Compression Level 0.0->500kb/s Compression Level 0.1->320kb/s Compression Level 0.2->256kb/s Compression Level 0.3->224kb/s Compression Level 0.4->192kb/s Compression Level 0.5->160kb/s Compression Level 0.6->128kb/s Compression Level 0.7->112kb/s Compression Level 0.8->96kb/s Compression Level 0.9->80kb/s Compression Level 1.0->64kb/s } res_sf_command:=-1; res_sf_command := sf_command_pointer(StreamOut[x].Data.HandleSt, SFC_SET_COMPRESSION_LEVEL, @compression_level, sizeof(compression_level) ); if res_sf_command = SF_TRUE then begin //SF_TRUE // compression_level:=1.0; end else if res_sf_command = SF_FALSE then begin //SF_FALSE // compression_level:=1.0; end; {$endif} end else if fileformat = 4 then begin //by trustfm // mp3 file {$IF DEFINED (sndfile)} StreamOut[x].FileBuffer.FileFormat := 4; StreamOut[x].Data.TypePut := 6; sfInfo.format := SF_FORMAT_MPEG Or SF_FORMAT_MPEG_LAYER_III; sfInfo.channels := StreamOut[x].Data.Channels; sfInfo.frames := streamOut[x].Data.Wantframes; SFinfo.samplerate := StreamOut[x].FileBuffer.wSamplesPerSec; SFinfo.seekable := 0; StreamOut[x].Data.Enabled := True; StreamOut[x].Data.HandleSt := sf_open (pchar (FileNamepath), SFM_WRITE, sfInfo); { https://github.com/libsndfile/libsndfile/issues/1008 Sample rate mode can be changed using SFC_SET_BITRATE_MODE Default is variable (constant quality), but average and constant bitrate are also supported for MP3. Sample rate value can be changed indirectly using SFC_SET_COMPRESSION_LEVEL (https://github.com/libsndfile/libsndfile/blob/c81375f070f3c6764969a738eacded64f53a076e/docs/command.md#sfc_set_compression_level). (The comment in the documentation about only supporting Voribs/Flac should be updated) For setting the compression, pass a value between 0.0 (max bitrate, min compression) and 1.0 (min bitrate, max compression). How the value is interpreted depends on the bitrate mode. For VBR, it translates to lame_set_VBR_qaulity(). 0.0 -> 0.0 (highest quality), 1.0 -> 10.0 (lowest quality) I'd recommend using VBR and just tweaking the quality as required. This is similar to other lossy formats. For ABR and CBR, it translates to [0.0, 1.0] to the bitrate values of [highest bitrate possible, lowest bitrate possible]. The possible bitrates depending on the MPEG spec version. For 32000Hz and higher (MPEG 1.0), [0.0, 1.0] -> [320kbps, 32kbps] For 16000Hz up to 32000Hz (MPEG 2.0), [0.0, 1.0] -> [160kbps, 8kbps] For under 16000Hz (MPEG "2.5") [0.0, 1.0] -> [64kbps, 8kbps] (See https://github.com/libsndfile/libsndfile/blob/master/src/mpeg_l3_encode.c#L194) You can retrieve the current bitrate using sf_get_byterate(), multiplying the result by 8. } { //This setting does not work currently it is always SF_BITRATE_MODE_VARIABLE //Set bitrate mode. SFC_GET_BITRATE_MODE was added for MP3 support //The bitrate mode is one of: //SF_BITRATE_MODE_CONSTANT 800 Constant bitrate. //SF_BITRATE_MODE_AVERAGE 801 Average bitrate. //SF_BITRATE_MODE_VARIABLE 802 Variable bitrate. bitrate_mode:=SF_BITRATE_MODE_VARIABLE; res_sf_command:=-1; res_sf_command := sf_command_pointer(StreamOut[x].Data.HandleSt, SFC_SET_BITRATE_MODE, @bitrate_mode, SizeOf(bitrate_mode) ); if res_sf_command = SF_TRUE then begin //SF_TRUE compression_level:=1.0; end else if res_sf_command = SF_FALSE then begin //SF_FALSE compression_level:=1.0; end; } //Set the Variable Bit Rate encoding quality. //The encoding quality value should be between 0.0 (lowest quality) and 1.0 (highest quality). //Currently this command is only implemented for FLAC and Ogg/Vorbis files. //It has no effect on un-compressed file formats. //vbr_encoding_quality:=1.0; res_sf_command:=-1; res_sf_command := sf_command_pointer(StreamOut[x].Data.HandleSt, SFC_SET_VBR_ENCODING_QUALITY, @vbr_encoding_quality, sizeof(vbr_encoding_quality) ); if res_sf_command = SF_TRUE then begin //compression_level:=1.0; end else if res_sf_command = SF_FALSE then begin //compression_level:=1.0; end; //Set the compression level. //The compression level should be between 0.0 (minimum compression level) and 1.0 (highest compression level). //Currently this command is only implemented for MP3 , FLAC and Ogg/Vorbis files. //It has no effect on uncompressed file formats. // [0.0, 1.0] -> [320kbps, 32kbps] { Compression Level 0.0->320kb/s Compression Level 0.1->256kb/s Compression Level 0.2->200kb/s Compression Level 0.3->180kb/s Compression Level 0.4->165kb/s Compression Level 0.5->128kb/s Compression Level 0.6->112kb/s Compression Level 0.7->100kb/s Compression Level 0.8->96kb/s Compression Level 0.9->80kb/s Compression Level 1.0->64kb/s } //compression_level:=0.9; res_sf_command:=-1; res_sf_command := sf_command_pointer(StreamOut[x].Data.HandleSt, SFC_SET_COMPRESSION_LEVEL, @compression_level, sizeof(compression_level) ); if res_sf_command = SF_TRUE then begin //SF_TRUE //compression_level:=1.0; end else if res_sf_command = SF_FALSE then begin //SF_FALSE //compression_level:=1.0; end; {$endif} end else begin // wav file StreamOut[x].FileBuffer.Data := TFileStream.Create (filenamepath,fmCreate); StreamOut[x].FileBuffer.Data.Seek (0, soFromBeginning); StreamOut[x].Data.TypePut := 0; IDwav := 'RIFF'; StreamOut[x].FileBuffer.Data.WriteBuffer (IDwav, 4); wFileSize := 0; StreamOut[x].FileBuffer.Data.WriteBuffer (wFileSize, 4); IDwav := 'WAVE'; StreamOut[x].FileBuffer.Data.WriteBuffer (IDwav, 4); IDwav := 'fmt '; StreamOut[x].FileBuffer.Data.WriteBuffer (IDwav, 4); wChunkSize := SizeOf (Header); StreamOut[x].FileBuffer.Data.WriteBuffer (wChunkSize, 4); case SampleFormat of 0: Header.wFormatTag := 3; else Header.wFormatTag := 1; end; //Header.wFormatTag := 1; Header.wChannels := StreamOut[x].FileBuffer.wChannels; Header.wSamplesPerSec := StreamOut[x].FileBuffer.wSamplesPerSec; Header.wBitsPerSample := StreamOut[x].FileBuffer.wBitsPerSample; Header.wBlockAlign := StreamOut[x].FileBuffer.wChannels * Header.wBitsPerSample Div 8; Header.wAvgBytesPerSec := StreamOut[x].FileBuffer.wSamplesPerSec * Header.wBlockAlign; Header.wcbSize := 0; StreamOut[x].FileBuffer.Data.WriteBuffer (Header, SizeOf (Header)); IDwav := 'data'; StreamOut[x].FileBuffer.Data.WriteBuffer (IDwav, 4); wChunkSize := 0; StreamOut[x].FileBuffer.Data.WriteBuffer (wChunkSize, 4); StreamOut[x].Data.Enabled := True; end; end; |
Administrator
|
Hello.
WoW ![]() I will study it deeply. Do you have a github account? If so, please do a pull-request. |
Hello unfortunately right now i do not have a github .
I can confirm that the Broadcaster Demo published here http://uos-forum.108.s1.nabble.com/Installing-IceCast-audio-web-server-td184.html#a1274 also works with the mp3 produced by this demo , so we can record and then broadcast in mp3 and ogg/vorbis tested on caster.fm server |
Administrator
|
Very nice.
![]() If you do not like github, there are mirrors on gitlab and codeberg and you may do pull-request also there: https://gitlab.com/fredvs/uos https://codeberg.org/fredvs/uos |
Free forum by Nabble | Edit this page |