Author Topic: BASS_WASAPI and CastInit  (Read 2489 times)

Ed1966

  • Posts: 51
BASS_WASAPI and CastInit
« on: 3 Feb '17 - 09:21 »
Hi :)

I want to stream Soundcard output to the ShoutCast webserver but there is a problem with: BASS_Encode_Start
I now only hear garbage noise and don't know if this snippet is correct. First time to use this.
Will you take a look and give me the right solution?

Code: [Select]
function WasapiProc(buffer:Pointer; length:DWORD; user:Pointer): DWORD; stdcall;
begin
  Result := BASS_ChannelGetData(Channel, buffer, length);
end;

begin
    BASS_WASAPI_Init(-3, 0, 0, 0, 0.5, 0, @WasapiProc, nil);
    BASS_WASAPI_GetInfo(&info); // get sample format info

    Channel := BASS_StreamCreate(info.freq, info.chans, BASS_STREAM_DECODE, STREAMPROC_DUMMY, 0);

    { Only Garbage, noise?? }
    BASS_Encode_Stop(Channel);
    Encoder := BASS_Encode_Start(Channel, 'lame -r -s 44100 -b %d -', [128], BASS_ENCODE_NOHEAD or BASS_ENCODE_AUTOFREE, nil, 0);
    BASS_Encode_CastInit(Encoder, PAnsiChar(FullServer), PAnsiChar(FullLogin), BASS_ENCODE_TYPE_MP3, 'Name', 'Url', 'Genre', nil, nil, 128, True);

    { Title is send correctly and visible server site }
    BASS_Encode_CastSetTitle(Encoder, PAnsiChar(FullTitle), nil);

    Bool := BASS_WASAPI_Start();
end;

I have tried this piece of code for BASS_Encode_Start but there is no sound.

Code: [Select]
  BASS_Encode_Stop(Channel);
  Encoder := BASS_Encode_Start(Channel, nil, BASS_ENCODE_PCM or BASS_ENCODE_NOHEAD or BASS_ENCODE_AUTOFREE, nil, 0);

Hope you see what I am doing wrong.
Regards,
Eduard.
« Last Edit: 3 Feb '17 - 09:36 by Ed1966 »

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #1 on: 3 Feb '17 - 16:18 »
Your WASAPIPROC function (WasapiProc) will be receiving floating-point data, so the "Channel" stream should also be floating-point; add BASS_SAMPLE_FLOAT to the BASS_StreamCreate call. Also add BASS_ENCODE_FP_16BIT to the BASS_Encode_Start call because LAME doesn't support floating-point data. You should also use the WASAPI device's "info.freq" value in the LAME command-line (it might not be 44100).

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #2 on: 4 Feb '17 - 06:23 »
I have added flags and modify Lame (I use latest version) and there is less garbage and sometimes I hear a voice (I play test mp3 song).
(Voice is unrecognizable and slow. Sound is very low)

Problem is not solved at this moment. Have you got more tips? 
Here is de full new code:

Code: [Select]
begin
  BASS_Free;
  BASS_Init(0, 44100, 0, Handle, nil);

  BASS_WASAPI_Init(-3, 0, 0, 0, 0.5, 0, @WasapiProc, nil);

  BASS_WASAPI_GetInfo(&info); // Result: Freq. 48000, 8 Channels

  Channel := BASS_StreamCreate(info.freq, info.chans, BASS_SAMPLE_FLOAT or BASS_STREAM_DECODE, STREAMPROC_DUMMY, 0);

  BASS_Encode_Stop(Channel);
  LameCommand := Format(AddBS(EncoderPath) + 'lame -r -s %d -b %d -', [info.freq, 256]);
  Comline := PChar(AnsiString(LameCommand));
  Encoder := BASS_Encode_Start(Channel, ComLine, BASS_ENCODE_FP_16BIT or BASS_ENCODE_NOHEAD or BASS_ENCODE_AUTOFREE, nil, 0);

  BASS_Encode_CastInit(Encoder, PAnsiChar(FullServer), PAnsiChar(FullLogin), BASS_ENCODE_TYPE_MP3, 'Name', 'Url', 'Genre', nil, nil, 128, True);

  BASS_Encode_CastSetTitle(Encoder, PAnsiChar(FullTitle), nil);

  BASS_WASAPI_Start();
end;

Or is it possible to put Encoder in MIXER and sent Mixer to CastInit?
Kind regards.
Eduard.
« Last Edit: 5 Feb '17 - 11:39 by Ed1966 »

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #3 on: 6 Feb '17 - 17:34 »
Code: [Select]
begin
  BASS_WASAPI_GetInfo(&info); // Result: Freq. 48000, 8 Channels

If the sample data has 8 channels, that will be a problem because MP3 doesn't support more than stereo. You will need to downmix it to stereo or just use the first 2 channels. A mixer (eg. BASS_Mixer_StreamCreate) could be used to implement either of those solutions. A splitter (eg. BASS_Split_StreamCreate) is also an option for the latter. In either case, you would need to change the dummy stream ("Channel") to a push stream, which you can plug into a mixer or splitter. Using a mixer could look something like this:

Code: [Select]
inputstream = BASS_StreamCreate(info.freq, info.chans, BASS_SAMPLE_FLOAT|BASS_STREAM_DECODE, STREAMPROC_PUSH, 0); // create push stream to hold WASAPI data
mixer = BASS_Mixer_StreamCreate(info.freq, 2, BASS_SAMPLE_FLOAT|BASS_STREAM_DECODE); // create stereo mixer
BASS_Mixer_StreamAddChannel(mixer, inputstream, 0); // plug input stream into mixer (add BASS_MIXER_DOWNMIX for downmixing)
BASS_Encode_Start(mixer, ...); // set encoder on mixer

...

DWORD CALLBACK WasapiProc(void *buffer, DWORD length, void *user)
{
BASS_StreamPutData(inputstream, buffer, length); // pass data to push stream
while (1) {
BYTE buf[20000]; // processing buffer
int r = BASS_ChannelGetData(mixer, buf, sizeof(buf)); // process the mixer (inc. send to encoder)
if (r <= 0) break; // done
}
}

Please see the documentation for details on the aforementioned functions.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #4 on: 7 Feb '17 - 08:31 »
Thanks Ian. Works great. 

Question: is there a possibility monitor and broadcast sound from my own Application only? 

Regards,
Eduard.

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #5 on: 7 Feb '17 - 13:43 »
I don't believe WASAPI has that option. What you could do is have your app send all playback through a mixer (eg. use BASS_Mixer_StreamAddChannel instead of BASS_ChannelPlay), and set the encoder on that.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #6 on: 8 Feb '17 - 09:34 »
Hi :)

I know how to put Streams into Mixer like this:
Code: [Select]
Mixer := BASS_Mixer_StreamCreate(44100, 2, BASS_UNICODE);
StreamLeft := BASS_StreamCreateFile(False, PChar(MusicLeft), 0, 0, BASS_STREAM_DECODE or BASS_UNICODE);
StreamRight := BASS_StreamCreateFile(False, PChar(MusicRight), 0, 0, BASS_STREAM_DECODE or BASS_UNICODE);
BASS_Mixer_StreamAddChannel(Mixer, StreamLeft, BASS_MIXER_BUFFER);
BASS_Mixer_StreamAddChannel(Mixer, StreamRight, BASS_MIXER_BUFFER);
BASS_ChannelPlay(Mixer, False);

But I want to use StreamLeft and StreamRight at full control because this is in my DJ program. With on both Streams PLAY, PAUSE, STOP and Progress for scroll position. But I don't know how to do that.

I was thinking of BASS_ChannelPlay(StreamLeft) but that is not working.

Do you have little code for me so I can do some experimental on this?

At first I was thinking about this piece of code but hear no sound. And maybe this is nog the right way.
Code: [Select]
FStream := BASS_StreamCreateFile(False, PChar(MusicFile), 0, 0, BASS_STREAM_DECODE or BASS_UNICODE);
While (Play_Pressed) do begin
  BASS_ChannelGetData(FStream, @FFTDataStream, BASS_DATA_FFT2048);
end;

Regards,
Eduard.

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #7 on: 8 Feb '17 - 17:01 »
I know how to put Streams into Mixer like this:
Code: [Select]
Mixer := BASS_Mixer_StreamCreate(44100, 2, BASS_UNICODE);
StreamLeft := BASS_StreamCreateFile(False, PChar(MusicLeft), 0, 0, BASS_STREAM_DECODE or BASS_UNICODE);
StreamRight := BASS_StreamCreateFile(False, PChar(MusicRight), 0, 0, BASS_STREAM_DECODE or BASS_UNICODE);
BASS_Mixer_StreamAddChannel(Mixer, StreamLeft, BASS_MIXER_BUFFER);
BASS_Mixer_StreamAddChannel(Mixer, StreamRight, BASS_MIXER_BUFFER);
BASS_ChannelPlay(Mixer, False);

But I want to use StreamLeft and StreamRight at full control because this is in my DJ program. With on both Streams PLAY, PAUSE, STOP and Progress for scroll position. But I don't know how to do that.

I was thinking of BASS_ChannelPlay(StreamLeft) but that is not working.

Do you have little code for me so I can do some experimental on this?

Do you mean you want to play/pause/stop the 2 sources individually? If so, you can do that by setting/removing the BASS_MIXER_PAUSE flag on each of them via BASS_Mixer_ChannelFlags:

Code: [Select]
BASS_Mixer_ChannelFlags(channel, BASS_MIXER_PAUSE, BASS_MIXER_PAUSE); // pause

...

BASS_Mixer_ChannelFlags(channel, 0, BASS_MIXER_PAUSE); // unpause

Note that there will be some extra latency added by the mixer due to buffering, ie. pausing/resuming won't be heard instantly. You can reduce the latency by reducing the mixer's playback buffer via the BASS_CONFIG_BUFFER option. If minimal latency is required, you could use WASAPI to play the mixer instead (call BASS_ChannelGetData on the mixer in your WASAPIPROC function).

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #8 on: 9 Feb '17 - 02:04 »
Think I now understand better. Add BASS_Mixer_ChannelSetPosition for position and BASS_Mixer_ChannelRemove to remove when loading new song.
This must than be right preparing left Player?
Code: [Select]
BASS_Mixer_ChannelRemove(channel);
BASS_Mixer_StreamAddChannel(mixer, channel, BASS_MIXER_BUFFER);
BASS_Mixer_ChannelFlags(channel, BASS_MIXER_PAUSE, BASS_MIXER_PAUSE); // pause
BASS_Mixer_ChannelSetPosition(channel, 0, BASS_POS_BYTE);
And always use BASS_ChannelPlay(mixer, False) or must this be True? 

Quote
If minimal latency is required, you could use WASAPI to play the mixer instead (call BASS_ChannelGetData on the mixer in your WASAPIPROC function).

What do you mean by that. I don't think I understand.

Regards,
Eduard.

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #9 on: 9 Feb '17 - 14:20 »
Think I now understand better. Add BASS_Mixer_ChannelSetPosition for position and BASS_Mixer_ChannelRemove to remove when loading new song.
This must than be right preparing left Player?
Code: [Select]
BASS_Mixer_ChannelRemove(channel);
BASS_Mixer_StreamAddChannel(mixer, channel, BASS_MIXER_BUFFER);
BASS_Mixer_ChannelFlags(channel, BASS_MIXER_PAUSE, BASS_MIXER_PAUSE); // pause
BASS_Mixer_ChannelSetPosition(channel, 0, BASS_POS_BYTE);
And always use BASS_ChannelPlay(mixer, False) or must this be True? 

You would usually use restart=FALSE in BASS_ChannelPlay calls, but you can use restart=TRUE if you want to clear the mixer's playback buffer, eg. perhaps after seeking.

If you want to add a source to a mixer in a paused state, it would be best to include the BASS_MIXER_PAUSE flag in the BASS_Mixer_StreamAddChannel call instead of calling BASS_Mixer_ChannelFlags afterwards.

Quote
If minimal latency is required, you could use WASAPI to play the mixer instead (call BASS_ChannelGetData on the mixer in your WASAPIPROC function).

What do you mean by that. I don't think I understand.

I was just saying that if you want low latency, then it would probably be better to play the mixer via WASAPI instead of using normal BASS playback. If you would like to try that, you can take a look at the CONTEST.C example code that's included in the BASSWASAPI package for a little demonstration.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #10 on: 10 Feb '17 - 03:05 »
Thank you for your effort and time. :)

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #11 on: 13 Feb '17 - 18:02 »
Hi, Maybe you can help me again?

BASS_ENCODE_TYPE_MP3 and 'Lame' is working fine.

Now I want to add OGG and AAC.

This is what I have created for 'BASS_ENCODE_TYPE_OGG':
Code: [Select]
LAME_COMMAND := Format('oggenc2 -r -M %d -m %d -R %d -C %d -', [SetCastBitRate, SetCastBitRate, WASAPI_INFO.freq, WASAPI_INFO.chans]); // BASS_ENCODE_TYPE_OGG
  Comline := PChar(AnsiString(LAME_COMMAND));
  GlobalEncoder := BASS_Encode_Start(OutputMixer, ComLine,
    BASS_ENCODE_FP_16BIT or BASS_ENCODE_NOHEAD or BASS_ENCODE_CAST_NOLIMIT, nil, nil);

And this one for 'BASS_ENCODE_TYPE_AAC':
Code: [Select]
LAME_COMMAND := Format('enc_aacplus - - --br 128000 --he --silent --rawpcm %d %d 16', [WASAPI_INFO.freq, WASAPI_INFO.chans]); // BASS_ENCODE_TYPE_AAC
  Comline := PChar(AnsiString(LAME_COMMAND));
  GlobalEncoder := BASS_Encode_Start(OutputMixer, ComLine,
    BASS_ENCODE_FP_16BIT or BASS_ENCODE_NOHEAD or BASS_ENCODE_CAST_NOLIMIT, nil, nil);

There is no sound. Can  you see what I am doing wrong with LAME_COMMAND?
I try a few but no results after hours searching forum. The 'BASS_Encode_CastInit' had the right BASS_ENCODE_TYPE.  ???

Regards,
Eduard.

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #12 on: 14 Feb '17 - 15:58 »
Is the BASS_Encode_Start call reporting success in its return value, ie. "GlobalEncoder" is not 0? If so, what does your BASS_Encode_CastInit call look like, and is that also reporting success?

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #13 on: 15 Feb '17 - 05:29 »
This is my log.

Code: [Select]
15-02-2017 05:59:53 ~ Broadcast: EncoderCommand: oggenc2 -r -M 128 -m 128 -R 48000 -C 2 -
15-02-2017 05:59:53 ~ Broadcast: EncoderContent: application/ogg
15-02-2017 05:59:53 ~ Broadcast: BASS_Encode_Start (1784)
15-02-2017 05:59:53 ~ Broadcast: BASS_Encode_CastInit (True)
15-02-2017 05:59:53 ~ Broadcast: BASS_WASAPI_Start (True)
15-02-2017 05:59:53 ~ Broadcast: BASS_Encode_CastSetTitle (True)

Code: [Select]
15-02-2017 06:03:08 ~ Broadcast: EncoderCommand: enc_aacplus - - --br 128000 --he --silent --rawpcm 48000 2 16
15-02-2017 06:03:08 ~ Broadcast: EncoderContent: audio/aacp
15-02-2017 06:03:08 ~ Broadcast: BASS_Encode_Start (1628)
15-02-2017 06:03:08 ~ Broadcast: BASS_Encode_CastInit (True)
15-02-2017 06:03:08 ~ Broadcast: BASS_WASAPI_Start (True)
15-02-2017 06:03:08 ~ Broadcast: BASS_Encode_CastSetTitle (False) [Some other mystery error]

OGG connects and see Title broadcasting but no sound.
AAC nothing visible on screen server side.

Do you think Encoder Command is correct?

Is it possible that streaming service (I received guest account to test my software) is not support OGG and/or AAC ??

I notice ACC+ ? Is that the same as AAC?

Regards,
Eduard.

Chris

  • Posts: 1796
Re: BASS_WASAPI and CastInit
« Reply #14 on: 15 Feb '17 - 09:02 »
Code: [Select]
-M 128 -m 128

-M Specify a maximum bitrate in kbps. Useful for streaming applications.
-m Specify a minimum bitrate (in kbps). Useful for  encoding for a fixed-size channel.

 while
-b Choose a nominal bitrate to encode at. Attempt
                      to encode at a bitrate averaging this. Takes an
                      argument in kbps. By default, this produces a VBR
                      encoding, equivalent to using -q or --quality.

so try -b 128

About AAC AAC+
thats are 2 different Encoders
AAC  Low Quality  Encoder
aacPlus v2  High Quality  Encoder

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #15 on: 15 Feb '17 - 15:36 »
Is it possible that streaming service (I received guest account to test my software) is not support OGG and/or AAC ??

What software is the streaming service running? I notice you mentioned Shoutcast in the 1st post. Shoutcast doesn't supports OGG, but it should support AAC. Have you tried using the pre-compliled CAST.EXE example that's included in the BASSenc package (C\BIN folder) to connect to the server? If not, you could give that a try and see what results you get.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #16 on: 16 Feb '17 - 04:18 »
I have tried CAST.EXE but could not test it with AAC.

Thanks Ian (and Chris) for help and information. I will do some tests this weekend.

Regards,
Eduard.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #17 on: 16 Feb '17 - 09:27 »
To continued my journey for Broadcasting. Here is another question. The microphone.
See code:

Code: [Select]
function StartMicroPhone: Boolean;
begin
  { Initialize BASS WASAPI input }
  Result := ExBASS_WASAPI_Init(-2, 0, 0, 0, 0.0, 0, @DuffRecording, nil);
  MicroSetDevice := ExBASS_WASAPI_GetDevice();

  { Create a stream to receive the data }
  Result := ExBASS_WASAPI_GetInfo(&WASAPI_INFO);
  MicroInputStream := ExBASS_StreamCreate(WASAPI_INFO.freq, WASAPI_INFO.chans, BASS_SAMPLE_FLOAT or BASS_STREAM_DECODE, STREAMPROC_PUSH, nil);

  { Initialize default output device (and measure latency) }
  Result := ExBASS_WASAPI_Init(-1, 0, 0, 0, 0.4, 0.05, @OutputRecording, nil);

  MicroOutputDevice := ExBASS_WASAPI_GetDevice();
  Result := ExBASS_WASAPI_GetInfo(&WASAPI_INFO);

  // Create a mixer to feed the output device
  MicroOutputMixer := ExBASS_Mixer_StreamCreate(WASAPI_INFO.freq, WASAPI_INFO.chans, BASS_SAMPLE_FLOAT or BASS_STREAM_DECODE);
  Result := ExBASS_Mixer_StreamAddChannel(MicroOutputMixer, MicroInputStream, 0); // plug in the input stream

  ExBASS_WASAPI_SetDevice(MicroSetDevice); // set device context to input
  ExBASS_WASAPI_Start(); // start it

  ExBASS_WASAPI_SetDevice(MicroOutputDevice); // set device context to output
  ExBASS_WASAPI_Start(); // start it
end;


Sound is good but there is a small delay. Is there any improvement to minimize delay? Or is this the best way.
I don't have tested RecordStart but look at forum there is more delay. Correct? 

Regards,
Eduard.

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #18 on: 16 Feb '17 - 14:36 »
The delay there is mostly determined by the output buffer (rather than the input/recording buffer). So for lower latency, you will need to reduce the size of that. You could try event-driven buffering, which will automatically use a smallish buffer in shared mode (usually 30ms), like this:

Code: [Select]
  Result := ExBASS_WASAPI_Init(-1, 0, 0, BASS_WASAPI_EVENT, 0, 0, @OutputRecording, nil);

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #19 on: 17 Feb '17 - 05:48 »
Nice. Thank you.

Maybe you can add:  BASS_WASAPI_EVENT = 16; in Dynamic_WASAPI.pas because it's missing.

Regards,
Eduard.


Chris

  • Posts: 1796
Re: BASS_WASAPI and CastInit
« Reply #20 on: 17 Feb '17 - 09:39 »
If you are working with the "dynamic bass* Units" be shure to compare them with the "static bass* Units" because the Dynamic Units are from 2011.
« Last Edit: 17 Feb '17 - 13:17 by Chris »

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #21 on: 18 Feb '17 - 10:35 »
Yes, Chris I known about this. But I thought there was some update if needed.
All your help make me create a better program and thanks for this.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #22 on: 23 Feb '17 - 19:06 »
Now everything is working fine (MP3, OGG (IceCast) , AAC). I stream it from my free Jukebox.
Question became here if it is possible to broadcast to MP3 and AAC at the same time? (two different Servers)
I think use for multi : BASS_Encode_CastInit ?
What can I do? Object or is there a way to do this in same code?

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #23 on: 24 Feb '17 - 12:35 »
To broadcast to 2 servers, you can call BASS_Encode_Start and BASS_Encode_CastInit twice, once for each server.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #24 on: 25 Feb '17 - 07:26 »
And can I use the same OutputMixer? (Look back for source)

Encoder1 := BASS_Encode_Start(OutputMixer, ...
BASS_Encode_CastInit(Encoder1, ...

Encoder2 := BASS_Encode_Start(OutputMixer, ...
BASS_Encode_CastInit(Encoder2, ..

Must do some rewriting so must know for sure.

Regards,
Eduard.

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #25 on: 27 Feb '17 - 13:32 »
Yes, you can have multiple encoders set on the same BASS channel.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #26 on: 27 Feb '17 - 16:07 »
Thank you.  :D

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #27 on: 6 Mar '17 - 17:24 »
Quote
Maybe a little off topic.
But for AAC do you need driver codex?
And what must I do? I can't stream AAC here. Source is good.


Solved. Channel problem for broadcast. 8 > now 2!
« Last Edit: 7 Mar '17 - 05:18 by Ed1966 »

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #28 on: 18 Mar '17 - 08:35 »
I have some problems casting to ShoutCast server. Sometimes sound seems to be hold for milliseconds and when takes longer some Auto-DJ takes over for few seconds.
Now I think solved this but is this the right solution?

Old situation:
Encoder := BASS_Encode_Start(OutputMixer, ComLine, BASS_ENCODE_FP_16BIT or BASS_ENCODE_NOHEAD
    or BASS_ENCODE_CAST_NOLIMIT, nil, nil);

New situation:
Encoder := BASS_Encode_Start(OutputMixer, ComLine, BASS_ENCODE_FP_16BIT or BASS_ENCODE_NOHEAD
    or BASS_ENCODE_CAST_NOLIMIT or BASS_ENCODE_QUEUE, nil, nil);

You see I add: BASS_ENCODE_QUEUE
And set BASS_CONFIG_ENCODE_QUEUE to ZERO.

So, is this the right way or are there other solutions?

Thanks,
Eduard.



Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #29 on: 20 Mar '17 - 15:24 »
Is the server's local playback sometimes stuttering when encoding it? If so, adding the BASS_ENCODE_QUEUE flag could indeed help; it sends the sample data to the encoder asynchronously so that decoding/playback isn't delayed.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #30 on: 21 Mar '17 - 15:41 »
The stuttering was kind of the problem. Look fine now. Thanks.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #31 on: 22 Mar '17 - 11:23 »
Do you have some information regarding: BASS_Encode_CastSendMeta
I can not find anything. I want to send cover picture.
Working in Delphi but C is welcome.

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #32 on: 22 Mar '17 - 14:49 »
Note that BASS_Encode_CastSendMeta only works with Shoutcast 2 servers. You can find details on the available metadata options here:

   http://wiki.winamp.com/wiki/SHOUTcast_2_(Ultravox_2.1)_Protocol_Details

For example, you could send a JPEG album cover like this:

Code: [Select]
BASS_Encode_CastSendMeta(encoder, 0x4100, data, length);

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #33 on: 23 Mar '17 - 05:36 »
Thank you. Found this one for use with Delphi so I can figure it out.

const
  BASS_METADATA_BIN_ALBUMART_JPG = 16640

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #34 on: 1 Apr '17 - 11:46 »
There are some stuttering even with buffer enabled. Not al the time but when I do some work in Jukebox. WASAPI is Threaded?
Can I give this Thread some flag to give full rights? If you understand. Maybe is IDLE when I select songs or whatever?

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #35 on: 3 Apr '17 - 15:13 »
Is your WASAPIPROC callback function (or DSPPROC/etc) doing anything that has to wait for another thread, eg. perhaps UI updates? If so, that stuff should be moved out of the callback function. For example, a callback function could post a message to the main thread, and the message handler does the UI update.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #36 on: 5 Apr '17 - 07:55 »
For Loopback I use (delphi)
Code: [Select]
function WasapiProcPush(buffer:Pointer; length:DWORD; user:Pointer): DWORD; stdcall;
begin
  { Pass data to push stream }
  BASS_StreamPutData(LocalInputChannel, buffer, length);
  Result := BASS_ChannelGetData(LocalOutputMixer, buffer, length);
end;
and STREAMPROC_PUSH:
Code: [Select]
LocalInputChannel := BASS_StreamCreate(INFO.freq, INFO.chans, BASS_SAMPLE_FLOAT or BASS_STREAM_DECODE, STREAMPROC_PUSH, nil);

Seems to be correct? If so than there is some server problem.

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #37 on: 5 Apr '17 - 14:33 »
Please also show what the LocalOutputMixer's BASS_Mixer_StreamCreate call looks like, and the BASS_Encode_Start call. Also confirm what device you are capturing from, and does capturing from a different device make any difference?

In your previous post you mentioned that the problem happens when you "do some work in Jukebox". Is that on the server PC or the client PC? Also, what client are you using and what buffering is it doing? Does the problem happen if you try playing the stream with a different client, eg. XMPlay or Winamp?

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #38 on: 6 Apr '17 - 10:58 »
Code: [Select]
  {  -3 = default loopback input device }
  Result := BASS_WASAPI_Init(-3, 0, 0, 0{Flags}, 0.5, 0, @WasapiProcPush, nil);
Code: [Select]
  { Create stereo mixer }
  LocalOutputMixer := BASS_Mixer_StreamCreate(INFO.freq, 2, BASS_SAMPLE_FLOAT or BASS_STREAM_DECODE);
Code: [Select]
  Encoder := BASS_Encode_Start(LocalOutputMixer, ComLine, BASS_ENCODE_FP_16BIT or BASS_ENCODE_NOHEAD
      or BASS_ENCODE_CAST_NOLIMIT or BASS_ENCODE_QUEUE, nil, nil);

This code should be good, I think.
Now is much better. Think Server setting error. not mine but they have new one.
Sometimes connection (Auto DJ) break but I think it's client Latency. I don't know solution in code so must be sever side.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #39 on: 23 Apr '17 - 18:13 »
I have one more problem, hope I can ask this after long run here.

Everything is working but the only problem is difference between:
BASS_ENCODE_COUNT_OUT  and  BASS_ENCODE_COUNT_CAST.

With broadcasting client the difference is always 4096 or higher. When it reaches about 12288 the server is lost for few seconds. No sound on the radio.
BASS_ENCODE_COUNT_QUEUE_LIMIT is set to approximately 10000ms, that's enough because after buffer filled to 2000ms there is also server lost for few seconds.

You can see code above in this topic witch i am using. But we talked about that and that was good.
And I use: BASS_ENCODE_FP_16BIT or BASS_ENCODE_NOHEAD  or BASS_ENCODE_CAST_NOLIMIT or BASS_ENCODE_QUEUE (Encoder_Start)

Do you know a solution about this problem?
Is this maybe a BASS_STREAM_DECODE problem in the Loopback. I think I read something about this.

Thank you.
Regards,
Eduard. 
« Last Edit: 24 Apr '17 - 02:07 by Ed1966 »

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #40 on: 24 Apr '17 - 17:32 »
Perhaps the sending to the server is timing-out sometimes. You can detect that by requesting notifications via BASS_Encode_SetNotify. Do you receive any BASS_ENCODE_NOTIFY_CAST_TIMEOUT notifications? If you do, you could try raising the BASS_CONFIG_ENCODE_CAST_TIMEOUT setting via BASS_SetConfig. Please see the BASS_CONFIG_ENCODE_CAST_TIMEOUT documentation for details.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #41 on: 24 Apr '17 - 19:23 »
I have set notify 'BASS_Encode_SetNotify' but that is not the problem. I receive message if something is wrong.

Using Centova Cast for broadcasting and the Centova server is located in America and I live in the Netherlands. Could this be the problem? Some distance problems?

I have tested all possibilities and can't get the right code, it must be right here  ???

Or have you one more thought?

Chris

  • Posts: 1796
Re: BASS_WASAPI and CastInit
« Reply #42 on: 24 Apr '17 - 19:25 »
Icecast or Shoutcast Server ?

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #43 on: 24 Apr '17 - 19:26 »
ShoutCast

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #44 on: 25 Apr '17 - 14:50 »
I have set notify 'BASS_Encode_SetNotify' but that is not the problem. I receive message if something is wrong.

OK, so you are using BASS_Encode_SetNotify and there are no BASS_ENCODE_NOTIFY_CAST_TIMEOUT notifications?

Another thing to check is whether the encoder is started before BASS_Encode_CastInit is called. That could result in BASS_ENCODE_COUNT_OUT being higher than BASS_ENCODE_COUNT_CAST. To avoid that, the encoder should be created in a paused state (BASS_ENCODE_PAUSE), and then unpaused (BASS_Encode_SetPaused) after BASS_Encode_CastInit is called.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #45 on: 25 Apr '17 - 17:47 »
There are no BASS_ENCODE_NOTIFY_CAST_TIMEOUT notifications!
I can test it tomorrow morning because now the station is busy. DJ is online.

EDIT:
After testing different between OUT and CAST is 90% zero, that's nice. Sometimes 4096/8192 for moment. But always back to zero.

Next situation because Auto-DJ sever side is not yet over.
I notice that buffer (10000ms) sometimes runs full to about 4000-5000ms and start the Auto-DJ at server side.
Do you know how to fix this and/or what is the problem?

Using:
22-05-2014  16:22           653.312 lame.exe
22-05-2014  16:22           519.680 lame_enc.dll
Is this the latest? I don't see newer.

Regards,
Eduard.

« Last Edit: 26 Apr '17 - 08:12 by Ed1966 »

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #46 on: 26 Apr '17 - 16:21 »
Next situation because Auto-DJ sever side is not yet over.
I notice that buffer (10000ms) sometimes runs full to about 4000-5000ms and start the Auto-DJ at server side.
Do you know how to fix this and/or what is the problem?

I'm not entirely sure what you mean. Can you give a bit more info on the problem, eg. what is its effect?

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #47 on: 27 Apr '17 - 09:16 »
Set value for BASS_ENCODE_COUNT_QUEUE_LIMIT at 10000ms (3528000 bytes)
This value is growing:  BASS_ENCODE_COUNT_QUEUE sometimes up to 5000ms.
When this is happening de music is lost and Centova cast switch to Auto-DJ.
Sometimes BASS_ENCODE_COUNT_QUEUE_FAIL value.

Is this my problem, do to Worthless internet stream? I am not the only one.
I broadcast from the Netherlands to Centova server America. Centova casting sent this to host (website) server in Netherlands, and I listen to this stream.

Main fact, is this coding problem or Centova problem?
If you look back in this topic you see nothing strange coding. I only monitor Loopback and sent it out. Try with different test sources.

Using:
{ BASS_ENCODE_TYPE_MP3 }
Result := Format('lame -r -s %d -b %d -', [AFrequency, ABitRate]); (44100, 256)

Maybe you can explain what to do?
If code is right maybe another Casting :(

Regards,
Eduard.



Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #48 on: 27 Apr '17 - 14:10 »
Is the BASS_ENCODE_COUNT_QUEUE value rising over time? If so, that means the source data is being provided more quickly than it's being encoded/casted. One possible reason for that could be if the bitrate is too high for the connection. What is your upstream bandwidth? It looks like your encoding bitrate is 256 kbps? You could try reducing that and see if it helps.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #49 on: 29 Apr '17 - 06:13 »
About 10Mbit upload speed. 
Tenth of  may I receive new internet provider and test everything again.
Thanks for your time for this moment.

Regards,
Eduard.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #50 on: 5 May '17 - 10:21 »
Broadcasting is now working fine. But I have minor question.

On some sound cards Microphone output is only audible on the left side. Is it possible with my WASAPI en StreamCreate microphone unit to merge left and right so you can here the voice left and right?

Regards,
Eduard.

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #51 on: 5 May '17 - 13:54 »
Is the problem that the microphone is stereo but it only has sound in the left channel? If so, you could use matrix mixing to replicate the left channel on the right channel, something like this:

Code: [Select]
BASS_Mixer_StreamAddChannel(mixer, source, BASS_MIXER_MATRIX);
float matrix[2][2]={
{1, 0}, // left out = left in
{1, 0} // right out = left in
};
BASS_Mixer_ChannelSetMatrix(source, matrix); // apply the matrix

Note this is assuming that the mixer is stereo. Adjust the matrix dimensions if not.

Another way to do it is to use the BASS_FX add-on's BASS_FX_BFX_MIX effect.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #52 on: 6 May '17 - 13:13 »
Found solution with BASS_MIXER_MATRIX. Thank you :)

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #53 on: 14 May '17 - 10:59 »
I try to sent ImageArt to Shoutcast v2. I get this result:

Code: [Select]
  const
      BASS_METADATA_BIN_ALBUMART_JPG = 16640;    // SHOUTcast v2 Cacheable Binary Metadata (Album art image/jpeg).

Result := BASS_Encode_CastSendMeta(Encoder,  BASS_METADATA_BIN_ALBUMART_JPG, LogoData, LogoStream.Size);

10-05-2017 10:53:31 ~ Broadcast: BASS_Encode_Start (1580)
10-05-2017 10:53:31 ~ Broadcast: BASS_Encode_CastInit (Default) (True)
10-05-2017 10:53:31 ~ Broadcast: BASS_Encode_CastSendMeta (1580, False) [Requested data is not available]

Coding in Delphi for init Image:
Code: [Select]
    LogoStream := TFileStream.Create(LogoFileName, fmOpenRead);
    GetMem(LogoData, LogoStream.Size);
    LogoStream.Read(LogoData^, LogoStream.Size);

Is this my problem or is support v2 not actually right?



Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #54 on: 15 May '17 - 17:49 »
Is the BASS_Encode_CastSendMeta error code BASS_ERROR_NOTAVAIL? If so, that sounds like a Shoutcast 2 connection wasn't setup in the BASS_Encode_CastInit call, ie. a "streamid" wasn't provided?

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #55 on: 16 May '17 - 10:53 »
Yes, the Error message is BASS_ERROR_NOTAVAIL.
I will investigate further.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #56 on: 6 Jun '17 - 09:37 »
Hi,

I have little question.

I use WASAPI for Microphone and Line-in. Sometimes the sound is gone and only WASAPI Stop and then START will fix this. 
That is happening by some other users and for me difficult to check.
Maybe they use Windows sound to change something or other software that change something.

Is it better to add flag BASS_WASAPI_EXCLUSIVE?
Lot of work so I ask you first. And little afraid that it don't work with everybody.

Regards,
Eduard.

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #57 on: 6 Jun '17 - 17:19 »
When you say the sound "is gone", do you mean your WASAPIPROC stops getting called? What does BASS_WASAPI_IsStarted say at that point? It might be that another app has started using the device in exclusive mode. Can you check with the user if that is what happened? If your app uses the device in exclusive mode, it will prevent other apps doing that, but it will also prevent other apps using the device at all.

If you aren't already using it, please also try this latest BASSWASAPI build:

   www.un4seen.com/stuff/basswasapi.zip

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #58 on: 7 Jun '17 - 08:27 »
If WASAPI is really stopped I don't know. STOP and START will re-start so it's possible driver is stopped. Must do more check in program.
I think it's another app and the user don't understand. I know that some using echo software besides my music program. I now add choice for exclusive mode.

I was using 12 may 2015 version DLL. But the same size. Now replaced with the new one.

This is the correct way to check?

BASS_WASAPI_SetDevice(LineMonitorInputDevice);
Result := BASS_WASAPI_IsStarted;

Regards,
Eduard.
« Last Edit: 7 Jun '17 - 08:32 by Ed1966 »

Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #59 on: 7 Jun '17 - 16:12 »
Yes, if you have multiple WASAPI device initialized, then you should use BASS_WASAPI_SetDevice before BASS_WASAPI_IsStarted, to set the device of interest.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #60 on: 8 Jun '17 - 03:42 »
Thanks Ian for all your help  8) :)

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #61 on: 12 Jun '17 - 12:41 »
Now I little confused.

I Start WASAPI for input Microphone. Never Stop this!
When switch to ON and OFF I use the stream volume for the Mixer. But after do this he delay for Microphone is not right. Longer.
After STOP and START for WASAPI it's to start better. Why?
Must I do WASAPI start and Stop in place of volume to zero? to Microphone On and Off?

Regards,
Eduard.

 



Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #62 on: 12 Jun '17 - 17:14 »
Are you sending the captured microphone data to an output device? If so, which device (the microphone or output) are you stop/starting to remove the delay, and what size buffer is requested in its BASS_WASAPI_Init call?

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #63 on: 13 Jun '17 - 07:42 »
Using Microphone WASAPI to remove if delayed.

Code: [Select]
{ WASAPI callback - not doing anything with the data }
  function DuffRecording(buffer: Pointer; length: DWORD; user: Pointer): DWORD; stdcall;
  begin
    { Feed recorded data to output stream }
    Result := BASS_StreamPutData(MicrophoneInputStream, buffer, length);
  end;

  // Size buffer 0.1 works the same as 0.0
  Result := BASS_WASAPI_Init(ADevice, 0, 0, 0, 0.0, 0, @DuffRecording, nil);
  LogEntry('Microphone', 'BASS_WASAPI_Init', BASS_ErrorGetCode, Result);
 
  MicrophoneInputStream := BASS_StreamCreate(WASAPI_INFO.freq, WASAPI_INFO.chans, BASS_SAMPLE_FLOAT or BASS_STREAM_DECODE, STREAMPROC_PUSH, nil);
  LogEntry('Microphone', 'BASS_StreamCreate', MicrophoneInputStream, (BASS_ErrorGetCode = 0));
 
  // OUTPUT ONLY WHEN NOT STARTED BY BROADCAST!
  Result := BASS_WASAPI_Init(-1, 0, 0, BASS_WASAPI_EVENT, 0.0, 0, @OutputRecording, nil);
  LogEntry('SetOutput', 'BASS_WASAPI_Init_Output', BASS_ErrorGetCode, Result);
  WASAPIOuput_Start;

  Result := BASS_Mixer_StreamAddChannel(GlobalOutputMixer, MicrophoneInputStream, BASS_MIXER_MATRIX); // plug in the input stream
  LogEntry('SetOutput', 'BASS_Mixer_StreamAddChannel_Output', BASS_ErrorGetCode, Result);

  Result := BASS_Mixer_ChannelSetMatrix((MicrophoneInputStream, @MatrixMonoStereo);
  LogEntry('Microphone', 'BASS_Mixer_ChannelSetMatrix', BASS_ErrorGetCode, Result);

  Result := BASS_ChannelSetAttribute(MicrophoneInputStream, BASS_ATTRIB_VOL, 0);
  LogEntry('Microphone', 'BASS_ChannelSetAttribute', BASS_ErrorGetCode, Result);

  Result := BASS_WASAPI_SetDevice(MicrophoneInputDevice);
  Result := BASS_WASAPI_Start; // start it

Now when speaking I only do this:

BASS_ChannelSetAttribute(MicrophoneInputStream, BASS_ATTRIB_VOL, AVolume); // Speak
BASS_ChannelSetAttribute(MicrophoneInputStream, BASS_ATTRIB_VOL, 0); // Silence


Or is this better:

BASS_Mixer_ChannelRemove // Silence
BASS_Mixer_StreamAddChannel // Speak

I think the ChannelSetMatrix gives me a kind of feeling that it's a little more Delayed. Is this possible? 

Regards,
Eduard.




Ian @ un4seen

  • Administrator
  • Posts: 20152
Re: BASS_WASAPI and CastInit
« Reply #64 on: 13 Jun '17 - 16:25 »
Now when speaking I only do this:

BASS_ChannelSetAttribute(MicrophoneInputStream, BASS_ATTRIB_VOL, AVolume); // Speak
BASS_ChannelSetAttribute(MicrophoneInputStream, BASS_ATTRIB_VOL, 0); // Silence


Or is this better:

BASS_Mixer_ChannelRemove // Silence
BASS_Mixer_StreamAddChannel // Speak

Is the latter giving you lower latency? I don't think it should do. If anything, I would expect it to give much higher latency because data would be building up in MicrophoneInputStream (the mixer isn't taking it).

I think stopping and starting the microphone may be better:

Code: [Select]
  Result := BASS_WASAPI_SetDevice(MicrophoneInputDevice);
  Result := BASS_WASAPI_Stop(1); // stop it
...
  Result := BASS_WASAPI_SetDevice(MicrophoneInputDevice);
  Result := BASS_WASAPI_Start; // start it

I think the ChannelSetMatrix gives me a kind of feeling that it's a little more Delayed. Is this possible? 

No, matrix mixing doesn't add any extra latency.

Ed1966

  • Posts: 51
Re: BASS_WASAPI and CastInit
« Reply #65 on: 14 Jun '17 - 15:17 »
OK, I will try START / STOP and stop thinking about Microphone :)
Thanks.