Author Topic: Stream audio/ line out to Icecast in C#  (Read 135 times)

RobX

  • Guest
Stream audio/ line out to Icecast in C#
« on: 7 Mar '19 - 11:03 »
Hi,
I am trying for 2 weeks to stream the sound that comes from the speakers (audio out) and stream it to Icecast using LAME encoder.
If I use an existing MP3 file on the computer and stream it or recording the PC microphone, the streaming works great.

As far as I know, I can do it with Loopback recording or WASAPI capture.
I tried WASAPI in the past, can it worked with CSCORE library in C# - I could capture the sound output and save it to a file. but it didn't have icecast library so I didn't use it further.
I don't want to go to the control panel and enable stereo mix (if it is needed). I want everything to be done programmatically.
 
            BASS_WASAPI_DEVICEINFO info2 = new BASS_WASAPI_DEVICEINFO();
            for (int i = 0; BassWasapi.BASS_WASAPI_GetDeviceInfo(i, info2); i++)
            {
                Debug.WriteLine(i + " = " + info2.ToString());
            }

gives me a list of wasapi devices.  I chose "Front (Realtek High Definition Audio)".

rest of the code:

            // assign WASAPI input in shared-mode (replace 'deviceId' with the one you want to use)
                 _wasapi = new BassWasapiHandler(34, false, 44100, 2, 0f, 0f);
            // init and start WASAPI
              _wasapi.Init();
              int recordStream = _wasapi.InputChannel;
            //// double check, that the device is not muted externally
              if (_wasapi.DeviceMute)
            //     _wasapi.DeviceMute = false;
             _wasapi.Start();


how do I connect it to my icecast stream? Before that, when I stream the microphone in (working great), I used:

Bass.BASS_RecordInit(-1);   //start the micrphone
_recProc = new RECORDPROC(RecordingHandler);
 _recHandle = Bass.BASS_RecordStart(44100, 2, BASSFlag.BASS_SPEAKER_FRONT, _recProc ,IntPtr.Zero);
EncoderLAME lame = new EncoderLAME(_recHandle);
lame.InputFile = null;    //STDIN
lame.OutputFile = null;    //STDOUT
lame.LAME_Bitrate = (int)EncoderLAME.BITRATE.kbps_128;
lame.LAME_Mode = EncoderLAME.LAMEMode.Stereo;
lame.LAME_TargetSampleRate = (int)EncoderLAME.SAMPLERATE.Hz_44100;
lame.LAME_Quality = EncoderLAME.LAMEQuality.Quality;

ICEcast icecast = new ICEcast(lame);
 icecast.ServerAddress = "127.0.0.1";
 icecast.ServerPort = 8000;
icecast.Password = "hackme";
 icecast.PublicFlag = true;
icecast.Username = "source";

_broadCast = new BroadCast(icecast);
_broadCast.AutoReconnect = true;
_broadCast.Notification += new BroadCastEventHandler(OnBroadCast_Notification);
Bass.BASS_ChannelPlay(_recHandle, true);
_broadCast.AutoConnect();

if there's a better way then WASAPI, please recommend it to me... Thanks!!!

Ian @ un4seen

  • Administrator
  • Posts: 21593
Re: Stream audio/ line out to Icecast in C#
« Reply #1 on: 7 Mar '19 - 15:07 »
Rather than using the BASSWASAPI add-on for that, I would recommend using the loopback support in BASS 2.4.14, which includes resampling capability so that you don't have to record in the device's sample format. You can identify a loopback device in the BASS recording device list (from BASS_RecordGetDeviceInfo) by it having the BASS_DEVICE_LOOPBACK flag set. You could also use the BASSenc_MP3 add-on instead of LAME.EXE. Basically, something like this:

Code: [Select]
BASS_RecordInit(device); // initialize the loopback recording device
recording = BASS_RecordStart(44100, 2, BASS_RECORD_PAUSE, RecordProc, NULL); // setup recording (paused)
encoder = BASS_Encode_MP3_Start(recording, lameoptions, BASS_ENCODE_AUTOFREE, NULL, NULL); // set an MP3 encoder on it
BASS_Encode_CastInit(encoder, ...); // setup casting on the encoder
BASS_ChannelPlay(recording, false); // start the recording

Please see the documentation for details on the mentioned functions.

Robx

  • Guest
Re: Stream audio/ line out to Icecast in C#
« Reply #2 on: 7 Mar '19 - 17:22 »
When I list all the available recording devices (BASS_RecordGetDeviceInfo), only the microphone appears:
Microphone (Realtek High Definition Audio)
BASS_DEVICE_ENABLED, BASS_DEVICE_DEFAULT, BASS_DEVICE_INIT, BASS_DEVICE_TYPE_MICROPHONE

I want to record the sound that comes out of the speakers (line out).

Ian @ un4seen

  • Administrator
  • Posts: 21593
Re: Stream audio/ line out to Icecast in C#
« Reply #3 on: 7 Mar '19 - 17:49 »
Perhaps an old BASS.DLL version is being loaded? You can use BASS_GetVersion to check that. 2.4.14 is needed for loopback support.

Robx

  • Guest
Re: Stream audio/ line out to Icecast in C#
« Reply #4 on: 7 Mar '19 - 17:57 »
I downloaded the latest version...
int ver = Bass.BASS_GetVersion();

 ver = 33819912

I don't understand this number...

Ian @ un4seen

  • Administrator
  • Posts: 21593
Re: Stream audio/ line out to Icecast in C#
« Reply #5 on: 8 Mar '19 - 13:25 »
That's 0x02040d08 in hex, which means version 2.4.13.8, so you are indeed currently using an old version. You can get the latest version from the BASS webpage (click the download link at the top of page). You should place the BASS.DLL file alongside your app's EXE (not just somewhere in the system's path). If you're using BASS.Net then you can use Bass.LoadMe to specify the path.

Robx

  • Guest
Re: Stream audio/ line out to Icecast in C#
« Reply #6 on: 8 Mar '19 - 17:22 »
Thanks! it's working now.
One more thing, how do I see the current audio level (or volume) of the audio out?

Bass.BASS_GetVolume()

gives me -1 all the time...

Thank you!

aquinch

  • Posts: 13

RobX

  • Guest
Re: Stream audio/ line out to Icecast in C#
« Reply #8 on: 10 Mar '19 - 07:39 »
I want to get the volume and display it, not set it...

Ian @ un4seen

  • Administrator
  • Posts: 21593
Re: Stream audio/ line out to Icecast in C#
« Reply #9 on: 11 Mar '19 - 14:59 »
BASS_GetVolume gives the device's volume control setting (the slider in the Sound control panel), not the level of its output.

Do you want the level of your app's sound or the entire system's sound, ie. including other apps? BASS doesn't provide the latter, but you can get the level of a stream from BASS_ChannelGetLevel(Ex). Getting the level of the BASS output mix is also possible but more complicated. You would need to get the device's stream handle from BASS_StreamCreate (with proc=STREAMPROC_DEVICE) and then set a DSP function on it (via BASS_ChannelSetDSP) that measures the level of the sample data it receives. BASS_ChannelGetLevel(Ex) can't be used on a device stream.

Rotem H.S

  • Guest
Re: Stream audio/ line out to Icecast in C#
« Reply #10 on: 11 Mar '19 - 15:58 »
Ok thank you Ian.
So,  can I get the level of a stream from BASS_ChannelGetLevel(Ex)?  (for the loop recording of the audio out)
Or must I use the complicated version?

Ian @ un4seen

  • Administrator
  • Posts: 21593
Re: Stream audio/ line out to Icecast in C#
« Reply #11 on: 11 Mar '19 - 16:29 »
BASS_ChannelGetLevel(Ex) can be used on a recording channel.