Installing IceCast audio web server.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
20 messages Options
Reply | Threaded
Open this post in threaded view
|

Installing IceCast audio web server.

fredvs
Administrator
This post was updated on .
Hello.

Icecast is a audio stream server.
http://icecast.org

It can deal Opus files encapsulated in Ogg format.
https://opus-codec.org

Opus files can be encoded for voip (voice over ip) or for web-radios (sound
over ip).

To communicate with IceCast, libshout and his fpc header will be used.
https://github.com/xiph/Icecast-libshout 

Today we will install and test the server on Unix 64 bit systems.

1) Installing IceCast + libshout.so.

- Linux :
  # sudo apt-get install icecast2
  # sudo apt-get install libshout3

- FreeBSD :
  # sudo pkg install icecast2
  # sudo pkg install shout

2) Downloading libshout fpc header + demo from here:

   https://github.com/user-attachments/files/18526459/shout_demo.zip
   
   Uncompress it somewhere.

3) Testing the audio server on localhost:

# cd /directory/of/shout_demo

# sudo uos_icecast2 start // for linux

# sudo uos_icecast2_freebsd start // for freebsd

If connection is ok, you may check it that way:

In your favorite web-browser, enter as url: http://localhost:8000

Enter login: admin
         password: hackme

This should load the IceCast Status page.

Now run the fpc demo opus_shout_demo.pas to assign a mount-point on the
server:
 
   # cd /directory/of/shout_demo
   # fpc opus_shout_demo.pas
   # ./opus_shout_demo

If all ok, in the IceCast Status web-page, after refresh, a new mount-point
will be added.

Congratulations, your IceCast server is working and you have assigned your
first mount-point.

Fre;D

Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

trustfm
This post was updated on .
Hello the link https://sites.google.com/site/fredvsbinaries/shout_demo.tar.xz does not work .
Can this solution work under widows too ?  I can see libshout-64 only under Linux and Freebsd ...
Thanks
Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

fredvs
Administrator
Hello and welcome to uos forum.

>Hello the link https://sites.google.com/site/fredvsbinaries/shout_demo.tar.xz does not work .

Indeed, google site has removed the site and sadly I dont have copy of the shout-demo.  
The demo dates from 2017 and I dont have worked with shout form this time.
Also now I cannot re-jump into it because I dont have a machine to do the server.

To enable compilation of uos using shout, you need to uncomment in uos_define.inc that line:

{$DEFINE shout} // uncomment to enable IceCast-Shout audio web server.

Sorry, I cannot help anymore for shout, it should work for Windows too but only my first post of this forum could help.
Good luck.


Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

fredvs
Administrator
Re-hello.

Finally I found a copy of shout-demo.
There is indeed only the libraries of Linux and FreeBSD included but for windows it should be easy to find the dll in internet
https://github.com/user-attachments/files/18526459/shout_demo.zip
Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

trustfm
Thank you . I have tested the
uos_AddIntoIceServer function
i made a connection with the icecast server but i get no sound

Icecast status says
...
total_bytes_read 154093
total_bytes_sent 0   <-------
user_agent libshout/2.4.6

I think that has to do with the buffer size
I am trying
setlength(StreamOut[x].Data.Buffer, 960 * StreamOut[x].Data.Channels ); //960
but still i can transmit but not receive

Thanks in advance
Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

trustfm
Hello here is a demo of broadcasting an OGG file to an icecast server (i have tested it on listen2myradio)
https://www.trim.uk.to/broadcast-demo.zip 


*******************************

program opus_shout_demo;

//TrustFm
//Based on
//https://github.com/xiph/Icecast-libshout/blob/master/examples/example.c
//Tested with listen2myradio.com

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Classes,
  ctypes,
  uos_shout;


var
  ordir : string;
  err : integer = -1;
  major:cint;
  minor:cint;
  patch:cint;
  shhandle :shout_t = nil;


  read, total : cint ;
  ret: integer;
  strm: TFileStream;
  fnam: string;
  buff  : array [0..4096-1] of byte;



begin
  ordir := IncludeTrailingBackslash(ExtractFilePath(ParamStr(0)));



 {$if defined(linux)}
    if  sh_Load(ordir + 'libshout.so.3') = true
{$else}
   if  sh_Load(ordir + 'LibShout-freebsd64.so') = true
{$endif}

   then begin
 WriteLn('libshout loaded');
 err := 0 ;
end else
   WriteLn(ordir + 'libshout.so.3' + 'libshout not loaded')  ;

if err = 0 then begin
       WriteLn('libshout version: '+ pchar(shout_version(major, minor, patch)));

  shout_init();

  shhandle := shout_new();

  if assigned(shhandle) then  begin

      WriteLn('shhandle assigned');

      err := shout_set_host(shhandle, pchar('IP'));
      if err = SHOUTERR_SUCCESS then
      WriteLn('shout_set_host OK. Error: ' + inttostr(err)) else
      WriteLn('shout_set_host error: ' + pchar(shout_get_error(shhandle)));

      err := shout_set_protocol(shhandle, SHOUT_PROTOCOL_HTTP);
      if err = SHOUTERR_SUCCESS then
      WriteLn('shout_set_protocol OK. Error: ' + inttostr(err)) else
      WriteLn('shout_set_protocol error: ' + pchar(shout_get_error(shhandle)));

      err := shout_set_port(shhandle, PORT);
      if err = SHOUTERR_SUCCESS then
      WriteLn('shout_set_port OK. Error: ' + inttostr(err)) else
      WriteLn('shout_set_port error: ' + pchar(shout_get_error(shhandle)));

      err := shout_set_password(shhandle, pchar('PASS'));
      if err = SHOUTERR_SUCCESS then
      WriteLn('set_password OK. Error: ' + inttostr(err)) else
      WriteLn('set_password error: ' + pchar(shout_get_error(shhandle)));

      err := shout_set_mount(shhandle, pchar('/stream')); //mountpoint
      if err = SHOUTERR_SUCCESS then
      WriteLn('shout_set_mount OK. Error: ' + inttostr(err)) else
      WriteLn('shout_set_mount error: ' + pchar(shout_get_error(shhandle)));

      err := shout_set_user(shhandle, pchar('source')); //source
      if err = SHOUTERR_SUCCESS then
      WriteLn('shout_set_user OK. Error: ' + inttostr(err)) else
      WriteLn('shout_set_user error: ' + pchar(shout_get_error(shhandle)));

      err := shout_set_format(shhandle,  SHOUT_FORMAT_OGG ); //SHOUT_FORMAT_MP3 - SHOUT_FORMAT_OGG
      if err = SHOUTERR_SUCCESS then
      WriteLn('shout_set_format OK. Error: ' + inttostr(err)) else
      WriteLn('shout_set_format error: ' + pchar(shout_get_error(shhandle)));

      err := shout_open(shhandle);
      if err = SHOUTERR_SUCCESS then begin
        WriteLn('shout_open OK. Error: ' + inttostr(err));
      end else begin
        WriteLn('shout_open error: ' + pchar(shout_get_error(shhandle)));
      end;


      WriteLn('Press Enter to stop and quit.');


      total := 0;
      fnam:=ordir + '03.ogg';
      strm := TFileStream.Create(fnam, fmOpenRead or fmShareDenyWrite);


      strm.position := 0;
      repeat


        WriteLn(inttostr (sizeof(buff)));
        read := strm.Read(buff,sizeof(buff));

        if (read > 0) then begin
          ret := shout_send(shhandle, buff, read);
          if (ret <> SHOUTERR_SUCCESS) then begin
              WriteLn('shout_open error: ' + pchar(shout_get_error(shhandle)));
              break;
          end;
        end else begin
          break;
        end;


        WriteLn('delay is :' + inttostr(shout_delay(shhandle)) );
        shout_sync(shhandle);
        WriteLn('Position :' + inttostr (strm.Position) );


      until strm.Position>=strm.Size;


      readln();


      shout_free(shhandle);

      shout_shutdown;

      strm.Free;

  end else begin
      WriteLn('shhandle not assigned')  ;

 end;


end;

end.


********************************

Now i will try broadcast a stream encoding with opus
The uos_AddIntoIceServer function does not work for me . I have found that might a ogg container is needed for the stream

Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

fredvs
Administrator
WoW, congratulations!

Sadly I dont have a machine to test this, but will study your code deeply.

Many thanks.
Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

trustfm
Hello ! I managed to make an ogg streamer based on your libshout bindings .
Below are some changes that i have made to your lib

at uos_libsndfile
//by TrustFm
const
SFC_GET_CURRENT_SF_INFO = $1002;
SFC_SET_VBR_ENCODING_QUALITY = $1300;
SFC_SET_COMPRESSION_LEVEL    = $1301;
SFC_SET_BITRATE_MODE = $1305;

SF_BITRATE_MODE_CONSTANT = 800; //Constant bitrate.
SF_BITRATE_MODE_AVERAGE = 801; //Average bitrate.
SF_BITRATE_MODE_VARIABLE = 802; //Variable bitrate.



Also changed
//TrustFm
//var
//  sf_command_double: function(sndfile: TSNDFILE_HANDLE; command: ctypes.cint;
//  var Data: double; datasize: ctypes.cint): ctypes.cint; cdecl;
var
  sf_command_double: function(sndfile: TSNDFILE_HANDLE; command: ctypes.cint;
  var Data: ctypes.cdouble; datasize: ctypes.cint): ctypes.cint; cdecl;

   

****************************

at uos

function Tuos_Player.AddIntoFile (Filenamepath: PChar; SampleRate: CDouble;
                                 Channels: cint32; SampleFormat: cint32; FramesCount: cint32;
                                 FileFormat: cint32): 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);
//  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
  vbr_encoding_quality: ctypes.cdouble;
  compression_level: ctypes.cdouble;
  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;//was1.0
      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;


      {
      //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_CONSTANT;
      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;
      }

  {$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;    


*************************
finally at uos_shout

  shout_set_metadata: function(shhandle :Pshout_t; metadata:Pshout_metadata_t):cint;cdecl; //TrustFm var metadata:shout_metadata_t
  shout_metadata_new: function():Pshout_metadata_t;cdecl;
  shout_metadata_free: procedure(shhandle:Pshout_metadata_t);cdecl; //TrustFm var shhandle:shout_metadata_t
  shout_metadata_add: function(shhandle:Pshout_metadata_t; name:pchar; value:pchar):cint;cdecl; //TrustFm var shhandle:shout_metadata_t
   

I will come with a demo based on these modded files
The demo streams OGG and can be set the quality and the compression level  
Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

fredvs
Administrator
CONGRATULATION!

If, by chance you have a Github account, it will be wonderful to do a pull-request to uos with your modifs + add a demo in examples folder.
If you dont have a Github account, you could upload here in uos forum the zipped files of your modifs (button More/Upload a file.)

Also if you agree, give your name or nick-name so I can add you in uos-contibutors.

Once again, big wow and many thanks.

Fre;D

Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

trustfm
Yes i will just give me a couple of yours to clean up the code
Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

trustfm
Ok i am back
Here is the link
https://trim.uk.to/shout_demo8_public.zip

The broadcaster trasmitts OGG into an icecast server like listen2myradio or caster.fm
I lowered the bitrate in order to fit casterfm limitations

Some documentation

{
Made By TrustFm
Icecast does not accept silence streams so interupts the stream between two songs.
The uos_AddIntoIceServer (opus) solution did not worked with me (no sound after transmission).

Solution :
Step 1) Create a Noise Player and play in Loop id:0-1 (so icecast does not interupts)
silence-white-noise-amp-00001-10sec.ogg (not audible)
or
silence-white-noise-amp-01-10sec.ogg (audible for bug-fixing)
Step 2)Create an OGG recorder PlayerRecorder id:2
Step 3)Create a OGG broadcaster reading from the Recorded file
https://github.com/xiph/Icecast-libshout/blob/master/examples/example.c
}  


You can add and use as you like the code .
I am working on a larger project that needed this feature.
NOTICE : BUTT does not work with OGG + icecast if detects silence disconnects from the server .
The demo works :)

The part uos_AddIntoIceServer if it is changed just ignore it i was testing without any luck
Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

fredvs
Administrator
In reply to this post by fredvs
Many thanks.
I will study your code asap.
Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

trustfm
No problem you can use the code as you wish . I forgot to mention that it is a CodeTyphon project but can be converted in Lazarus easily
Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

fredvs
Administrator
Hum, if I translate it, it would be using MSEgui, much better to deal with all audio stuffs (LCL "eats" audio latency).
Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

fredvs
Administrator
Maybe it could interest you, web-player that can deal with mp3 or acc format:
https://github.com/fredvs/swp/releases/

It uses uos and MSEgui.
Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

trustfm
Wow ! thanks . I am not familiar with MSEgui .
Nice to see we have a lot of FreePascal options
my projects can be found at trustfm.net

Question > i have tried to make a simple VU meter like your SimplePlayer example but for the recorder . I couldnt make it to work. I added the InLoop fuction but does not work ...  
Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

fredvs
Administrator
Maybe take a look how it is done in SWP :  https://github.com/fredvs/swp/blob/main/src/webstreamer.pas
Or from the recorder of StrumPract: https://github.com/fredvs/strumpract/blob/main/src/recorder.pas

Without code I cannot help more.
Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

trustfm
Thank you i  had to enable (forgot )
uos_InputSetPositionEnable
uos_InputSetLevelEnable


********************

    // set position calculation (default is 1)
    // InputIndex : InputIndex of existing input
    // 0 => no calcul
    // 1 => calcul position.
    uos_InputSetPositionEnable (PlayerRecorderIndex, PlayerRecorderInputIndex,1);

    // set level calculation (default is 0)
    // InputIndex : InputIndex of existing input
    // 0 => no calcul
    // 1 => calcul before all DSP procedures.
    // 2 => calcul after all DSP procedures.
    // 3 => calcul before and after all DSP procedures.
    uos_InputSetLevelEnable(PlayerRecorderIndex, PlayerRecorderInputIndex, 2);

    //now calculate current position and Level volume in loop
    uos_LoopProcIn(PlayerRecorderIndex, PlayerRecorderInputIndex, @LoopProcPlayerRec);
Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

fredvs
Administrator
Indeed, by default calculation is disabled (not needed for "only playing").
Reply | Threaded
Open this post in threaded view
|

Re: Installing IceCast audio web server.

trustfm
This post was updated on .
Hello i managed to port the example in widows i had two problems to solve
1)shoutlib for windows that can be found here
https://github.com/xiph/Icecast-libshout/issues/9 

The pacakes from here
https://packages.msys2.org/packages/mingw-w64-ucrt-x86_64-libshout
did not worked i have load them successfully (all the dependancies) but when i transmit the program crashes ...

*********************

//TrustFm
function sh_Load(const libogg,libvorbis,libvorbisenc,libvorbisfile,libwinpthread,libshout :string) :boolean;
begin

  Result := False;
  if sh_Handle<>0 then begin
   Inc(ReferenceCounter);
   result:=true {is it already there ?}
  end else begin {go & load the library}

    if Length(libshout) = 0 then exit;

    sh_Handle:=DynLibs.SafeLoadLibrary(libogg);
    sh_Handle:=DynLibs.SafeLoadLibrary(libvorbis);
    sh_Handle:=DynLibs.SafeLoadLibrary(libvorbisenc);
    sh_Handle:=DynLibs.SafeLoadLibrary(libvorbisfile);
    sh_Handle:=DynLibs.SafeLoadLibrary(libwinpthread);
    sh_Handle:=DynLibs.SafeLoadLibrary(libshout);


    if sh_Handle <> DynLibs.NilHandle then begin {now we tie the functions to the VARs from above}

        Pointer(shout_init):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_init'));
        Pointer(shout_shutdown):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_shutdown'));
        Pointer(shout_version):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_version'));
        Pointer(shout_new):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_new'));
        Pointer(shout_free):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_free'));
        Pointer(shout_get_error):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_error'));
        Pointer(shout_get_errno):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_errno'));
        Pointer(shout_get_connected):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_connected'));
        Pointer(shout_set_host):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_host'));
        Pointer(shout_get_host):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_host'));
        Pointer(shout_set_port):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_port'));
        Pointer(shout_get_port):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_port'));
        Pointer(shout_set_agent):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_agent'));
        Pointer(shout_get_agent):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_agent'));
        Pointer(shout_set_tls):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_tls'));
        Pointer(shout_get_tls):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_tls'));
        Pointer(shout_set_ca_directory):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_ca_directory'));
        Pointer(shout_get_ca_directory):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_ca_directory'));
        Pointer(shout_set_ca_file):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_ca_file'));
        Pointer(shout_get_ca_file):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_ca_file'));
        Pointer(shout_set_allowed_ciphers):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_allowed_ciphers'));
        Pointer(shout_get_allowed_ciphers):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_allowed_ciphers'));
        Pointer(shout_set_user):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_user'));
        Pointer(shout_get_user):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_user'));
        Pointer(shout_set_password):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_password'));
        Pointer(shout_get_password):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_password'));
        Pointer(shout_set_client_certificate):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_client_certificate'));
        Pointer(shout_get_client_certificate):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_client_certificate'));
        Pointer(shout_set_mount):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_mount'));
        Pointer(shout_get_mount):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_mount'));
        Pointer(shout_set_name):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_name'));
        Pointer(shout_get_name):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_name'));
        Pointer(shout_set_url):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_url'));
        Pointer(shout_get_url):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_url'));
        Pointer(shout_set_genre):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_genre'));
        Pointer(shout_get_genre):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_genre'));
        Pointer(shout_set_description):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_description'));
        Pointer(shout_get_description):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_description'));
        Pointer(shout_set_dumpfile):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_dumpfile'));
        Pointer(shout_get_dumpfile):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_dumpfile'));
        Pointer(shout_set_audio_info):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_audio_info'));
        Pointer(shout_get_audio_info):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_audio_info'));
        Pointer(shout_set_meta):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_meta'));
        Pointer(shout_get_meta):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_meta'));
        Pointer(shout_set_public):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_public'));
        Pointer(shout_get_public):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_public'));
        Pointer(shout_set_format):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_format'));
        Pointer(shout_get_format):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_format'));
        Pointer(shout_set_protocol):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_protocol'));
        Pointer(shout_get_protocol):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_protocol'));
        Pointer(shout_set_nonblocking):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_nonblocking'));
        Pointer(shout_get_nonblocking):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_get_nonblocking'));
        Pointer(shout_open):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_open'));
        Pointer(shout_close):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_close'));
        Pointer(shout_send):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_send'));
        Pointer(shout_send_raw):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_send_raw'));
        Pointer(shout_queuelen):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_queuelen'));
        Pointer(shout_sync):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_sync'));
        Pointer(shout_delay):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_delay'));
        Pointer(shout_set_metadata):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_set_metadata'));
        Pointer(shout_metadata_new):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_metadata_new'));
        Pointer(shout_metadata_free):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_metadata_free'));
        Pointer(shout_metadata_add):=DynLibs.GetProcedureAddress(sh_Handle,PChar('shout_metadata_add'));

    end;

    Result := sh_IsLoaded;
    ReferenceCounter:=1;

  end;

end;



***********************


and
2)Recording from the speaker instead from the mic
For recording audio i installed latest version from realtek using
www.driverscape.com for finding my driver
I use Recording -> Stereo-Mix option
The WASAPI option did not worked for me .... (use the output as input ...)