19 Jun '13 - 13:08 *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
 
   Home   Help Search Login Register  
Pages: [1]
  Reply  |  Print  
Author Topic: No example for Dot Net Showing how to Encode Wav device to Mp3?  (Read 5015 times)
KayCee
Posts: 37


« on: 21 Jan '06 - 20:11 »
Reply with quoteQuote

Hello,

I have been all through the examples for the Dot Net Framework and it is lacking an example showing how to use bass encode from them, to encode to mp3 what is playing on the soundcard device for example...

This is puzzling as I was under the impression from radio42 that the dot net versions had all the examples I would need, or the same examples that the non-dotnet framework version for bass-encoder has.

Any assistance in this matter would be greatly appreciated, since I read another post from another user that was getting a crash on a continuous loop from inside vb 6, so looks like the only way to do this is to use dot net, but there are no examples.

Radio can you hook it up, how about those that I provided the links to?

Thanks,

KayCee
Logged
radio42
Posts: 4030


« Reply #1 on: 22 Jan '06 - 09:51 »
Reply with quoteQuote

You might take a look to the C# sample "Encoder" - which shows live recording to WMA.
And then there is a VB example called "AudioJoiner" which shows encoding to MP3...

I thought, that this is quite sufficient...
Logged
big_gun
Posts: 342


« Reply #2 on: 23 Jan '06 - 16:28 »
Reply with quoteQuote

AudioJoiner can encode to WMA, MP3 and OGG.

Rick
Logged
KayCee
Posts: 37


« Reply #3 on: 15 Feb '06 - 05:46 »
Reply with quoteQuote

on the fly, using stdin and stdout ?  So I can then send the buffered mp3 data to a server ?
Logged
radio42
Posts: 4030


« Reply #4 on: 15 Feb '06 - 13:42 »
Reply with quoteQuote

What kind of server you want the data to send to?

The default BASSenc sends the data to stdout and might receive the encoded data via the encoder callback from stdin...you you might use the encoder callback to receive the encoded data and send to what ever server (if your server accepts raw encoded MP3 data!).

If you are trying to send the data to a SHOUTcast server the data to send will not be the same as returned by the encoder, since SHOUTcast data also contains some meta data. Here I would suggest using BASS_WADSP and use a WinampDSP plugin to send the data to a SHOUTcast server...
Logged
KayCee
Posts: 37


« Reply #5 on: 22 Apr '06 - 03:44 »
Reply with quoteQuote

Shoutcast or Icecast Radio42!  Long time no see, sorry, I have been out of it here lately pushing hard to get this radio station pumping.  Now I have some freetime, and some new sourcecode to work from, which currently works with icecast and x-http servers.  The issue is the sourcecode is still in C++, and I prefer to work in Visual basic, or VB.Net if at all possible.

Now, I took your instructions about making sure no visual updates were done while encoding, and now it appears to encode, and I am not getting the runtime error anymore!  But!!!  I am not getting the mp3 encoded data streamed out to the server properly, or something, I attempt to listen and I hear nothing, and it disconnects from the server, because when the server does not get any data for a period of time, it drops the connection.

If you, and some of the forum frequent flyers can help me solve just a simple example showing how to encode whatever is playing on the soundcard mixer or wav device -> to -> either oggenc or lame.exe and then I want this encoded data deposited into a buffer of some sort, so I can merely take the data on a timer based operation and stream the data, after sending all my icy commands to initiate and get the OK200 response from the server.

Please email me, or msg me back!  My email is: comedy@pkradio.net

Thanks in advance, and I have a request for the new 2.3 version of bass and bassenc, make it easier to use with visual basic, meaning, more compatible with a custom type, and make it easier to stream what is encoded just like WMA.  Also, I 2nd the request for being able to transcode one encoding to multiple bitrates and being able to stream to multiple servers, I suggest at least 3, this is the perfect number, anyone streaming to more than 3 servers, needs to really be building their own custom setup anyway or be using more than one copy of an application or more than one client or source computer.

Please hit me back, I am eager to finish this project as soon as possible.  Thanks.

Crazy KayCee!
Logged
radio42
Posts: 4030


« Reply #6 on: 24 Apr '06 - 08:21 »
Reply with quoteQuote

So for streaming data to a SHOUTcast or Icecat Server why don't you use BASS_WADSP and a Winamp Source DSP plugin...?

Just encoding MP3 data with BASSenc and 'sending' it to the server is not sufficient. SHOUTcast and Icecast have their own format and protocol.
Logged
KayCee
Posts: 37


« Reply #7 on: 27 Apr '06 - 04:50 »
Reply with quoteQuote

I understand that Shoutcast has their own format, which I have completely figured out.  I have all my icy protocol stuff working fine.  What I can not get to work, is encoding any wav device to mp3 or ogg format, to a buffer that I can then send to the server once the handshake is complete and I get the OK200 response after initializing all the entries.

Using the Winamp DSP is not an option, as this is what we are trying to get away from.  Also, using ODDCast is not an option, as we can not include someone elses DSP Plugin into an application we want to do.

Did I mention I have it working fine with already encoded mp3 files, like if I have my application load an m3u playlist, it will load each one in success and stream it just fine using my protocol information.  I actually wrote the article that was listed at #1 on google for along time, about the Real Shoutcast ICY Protocol, also available on Planet Sourcecode.

I am just having a hard time getting bass to encode to a buffer, or to be able to setup a callback function, which will fire off the encoded mp3 or ogg data to the winsock control as needed, once the connection has already been established, and say I click the record button in my app, which should work, but doesn't for some reason.

;'(

I have been working on this for quite a while now, and am beginning to wonder if anyone else on here has done this or not.

What is the point of encoding the data to a buffer if you can't use it to send via a winsock control.

Thanks for any and all help you can provide.

KayCee
Logged
radio42
Posts: 4030


« Reply #8 on: 27 Apr '06 - 09:17 »
Reply with quoteQuote

I understand. I personally also would like to do so - but myself never figured out the SHOUTcast protocol (or had time to care about).
So may be you could share your code here once we figured all issues out.
I would be very much interested in adding native streaming support to my BASS.NET API if possible.

However, I guess all should be possible. But you need to make use of BASSenc in this case.
First BASSenc only works with encoders which exept stdin/out parameters, but "lame.exe" and "oggenc.exe" for example do so.

When using the BASSenc.BASS_Encode_Start method you might specify an ENCODEPROC callback.
In this callback function you will then receive the encoded data.
To have the encoded data received by a callback function, the encoder needs to be told to output to STDOUT (instead of a file) and to receive data from STDIN.

The issue around is now, that I guess SHOUTcast is requesting data from your connection...meaning it is not your application which pushes data to SHOUTcast, instead SHOUTcast is pulling data from your connection.

This means, that you would need a kind of synchronized mechanism at best. Meaning you wanted to call a method which gives you exactly the next chunk of encoded data.
The problem with the BASSenc ENCODEPROC is now, that any callback be nature is async.

But...
Internally, the sending of sample data to the encoder is implemented via a DSP callback on the channel.
That means when you play the channel (or call BASS_ChannelGetData if it's a decoding channel), the sample data will be sent to the encoder at the same time.

Solution:
In order to synchronize the callback with the SHOUTcast request for new encoded data you might want to do the following:
Within your Streaming-Method which needs the encoded data:
- Call BASS_ChannelGetData to request new data from your source stream (decoding!)
- wait until the ENCODEPROC callback has finished
- use a global variable to synchronize this
- use a global buffer for storing the encoded data

Pseudo-Code Example:
// define your sync trigger
public bool encoderReady = false;
// define a global buffer for encoded data
public short[] encBuffer;

// I will assume, you have already created a source decoding channel
// create the encoder (with default setting for lame)
BassEnc.BASS_Encode_Start(channel, "lame --alt-preset standard", BASSEncode.BASS_ENCODE_DEFAULT, myEndoderProc, 0);

// your Entry-Method
MyShoutcast(...)
{
  // request N new samples...
  // recalculte the requested data to real bytes M...SHOUTcast might request number of encoded samples
  M = ConvertNToM(N); // this might be the tricky part, but if using CBR it should be easy
  BASS_ChannelGetData( M ); // request bytes from your source stream, which will directly be encoded
  while ( !encoderReady )
  {
     Thread.Sleep(10);
  }
  encoderReady = false;
  // now the encBuffer should be ready with the next data...
  SendEncBufferToSHOUTcast( encBuffer, N );
}

myEndoderProc( buffer, N )
{
   ...here we receive the encoded data and copy it to a global encBuffer
   // dynamic alloc of the encBuffer
   if (encBuffer == null || encBuffer.Length < N)
       encBuffer = new short[N];

   // copy the encoded data to our global buffer
   MemCopy( buffer, encBuffer, N );

   // tell our system, that new data is ready
   encoderReady = true;
}
Logged
KayCee
Posts: 37


« Reply #9 on: 28 Apr '06 - 08:54 »
Reply with quoteQuote

Please see my other post, my friend, for all of the description that I have for the ICY Protocol.  It is very simple as you will see.  I will also post my handshake code here very soon as well.  I am not sure you understand about the give and take.  Shoutcast, once the handshake is made, and you receive the OK200 response, it will expect next Mp3 or OGG encoded data, hopefully with the header that describes what is coming next.  Then you merely continue to feed it mp3 data, in a continuous stream, from time to time if anything is changed in the initial values like Station name etc.. you would have to make a disconnect and reconnect, the only other data that would get sent during the transmission of the data, would be if it had scripts embeded in the stream, which if so, all it does is send a string with the current song title, and is not supported by all clients, so I would ignore doing the in stream scripts.

So, your first two lines in the MyShoutcast(...) are not really needed, as shoutcast doesn't tell you how many samples it wants.

but you are on the right track with the rest of your functions.

Thank you so much for helping, there are alot of other people out there, that simply turn a blind eye, and it has become something of a secret like it was when cavedog first brought out total annihilation, and people claimed they had written unit editors, but would not tell anyone how they did it.  Which in turn pissed me off to the point, I stayed up for 48 Hours straight and reverse engineered the 3do file format, and made THE FIRST DXF -> 3DO Convertor.  Then Kinboat joined in with me, and we made a kickass unit editor, that pissed off cavedog, they actually emailed us asking us to stop.  Which we ignored of course, because they told us, that our editor turned out better than their inhouse one.

Why did I tell you this story?

To give you a nudge to keep after it, I think you are on the right track for something awesome for all of us, and if you want my help on anything, just email me, or msg me, or post a reply here.

Thanks Radio42, Like the other guy said, you are a life saver!

Crazy KayCee! aka Ken aka StOrM3
Logged
radio42
Posts: 4030


« Reply #10 on: 28 Apr '06 - 13:35 »
Reply with quoteQuote

Sounds great! - and you are welcome!

Right, as I said, I never looked at the SHOUTcast protocol.
But if SHOUTcast is never asking for N number of sample data and your application can just send out as much mp3 encoded data to the server...how do you make sure not to send it out to fast to the server ?

However, things get much more easier...no internal ring buffer needed etc.

So then you could simply use the sync mechanism...and decide by yourself via a 'stupid' BASS_ChannelGetData call how much data you want to encode next.

Or, in case you want to do all in real-time (meaning you don't use a decoding channel, but send data as it is played out...). You could simply do the following:

a) Create a normal playing stream and start an encoder on it:
E.g.:
// create a stream
channel = Bass.BASS_StreamCreateFile(_fileName, 0, 0, BASSStream.BASS_DEFAULT);
// create the encoder (with default setting for lame)
BASS_Encode_Start(channel, "lame --alt-preset -", BASS_ENCODE_DEFAULT, myEndoderProc, 0);
// start the channel playing & encoding
Bass.BASS_ChannelPlay(channel, false);

Or as an alternative: use the Mixer-Output of BASSmix as the 'channel' to encode!

b) in your encoding callbach (where you receive the encoded data) you can directly send the encoded data to the SHOUTcast server:

private byte[] _encbuffer;
unsafe public myEndoderProc(int channel, IntPtr buffer, int length, int user)
{
   ...here we receive the encoded data and copy it to a global encBuffer
   // dynamic alloc of the _encbuffer
   if (_encbuffer == null || _encbuffer.Length < length)
       _encbuffer = new short[length];

   // copy the encoded data to our global buffer
   Marshal.Copy(buffer, _encbuffer, 0, length);

   // now we can send this data to the server
   // a) either directly here, e.g. "SendEncDataToServer(_encBuffer);
   // b) or async by invoking another callback delegate or thread
}


This can be done, since an Encoder procedure will be setup like any other DSP - except it will not receive raw pcm sample data but encoded mp3 data...

Where can I find your other posts about the ICY protocol?
THX - lets stay n contact...and I'll try to implement the SHOUTcast stuff to the BASS.NET API as well ;-)
Logged
KayCee
Posts: 37


« Reply #11 on: 28 Apr '06 - 16:42 »
Reply with quoteQuote

Right, okay check this out, here is how the shoutcast server and the source know what rate to accept data at..

Basically when you setup the protocol ICY stuff, you tell it what rate the mp3 data is encoded at ex. 24Kbps Mono 22050 Khz. which for example is about 2.9Kps, so what I was told, is if you setup a simple double buffer, one for encoded data, and one to encode from, (*NOTE*) this was before I found bass that encodes on the fly itself, prolly no need for the un-encoded buffer now, but still the same, you make like a 4K Buffer, or 8K depending on whatever you are encoding at, so that you always have a little more in the buffer than what you are sending, but not so much as to overwhelm your system, and slow it to a crawl, since the server will not receive it fast enough and eventually you will load up your memory, although it will continue to work.  I know for a fact, from my m3u example version, I used no buffering at all, except to create a single buffer the size of the mp3 file itself, each one that was loaded one after the other, and sent it all straight out the winsock to the shoutcast server, and it worked great!

Hope this helps clear the fog a little more.

I think we can setup some sort of a buffer and just monitor it to make sure it doesn't get to loaded down, if so, then delay pushing anymore into it, until it clears itself out.  I think this is why applications like SAM have a 30 Second delay in the broadcast, because when you have more than one server connection, ex. I have a 24K Mono, and a 64K MP3 Pro at stereo, and still only get like a 30 second delay, so it is managing the buffer pretty good.  I think if you buffer @ like 15-20 seconds of audio, then start sending, I think if the broadcaster or source is using broadband to broadcast it should not be an issue.  You have to have broadband anyways, as there is strict rules to how fast of a bitrate to setup vs. your internet connection speed, to deal with this issue, that shoutcast mentions.  Also, the server itself, is / or should be on a T1 or something similar and will handle the playing at the correct bitrate on its end, once the ICY bits are setup and the handshake is good to go.

So I say just make 2 - 4K Buffers, one you are filling up from the encoding callback, and one you are sending from to the winsock control, then you swap them.

I hope this is helping.

PS. I can't wait to look at his sample, this is going to rock with 3 of us working on it!

KayCee!

comedy@pkradio.net
Logged
Trek
Guest
« Reply #12 on: 8 May '06 - 19:32 »
Reply with quoteQuote

I'm very interested in this topic!  How are things going with it?  I too wanted to get away from the shoutcast DSP, but the Shoutcast server works fine.  Is there any source I can look at, preferebly in VB.NET? 

Thank you everyone that is working on this, I hope it's planned to share!
Logged
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.18 | SMF © 2013, Simple Machines