|
radio42
Posts: 4012
|
 |
« Reply #480 on: 23 Jul '08 - 09:04 » |
Quote
|
Why don't you ask Tomson about it. I guess they also have contracts for individuals...
|
|
|
|
|
Logged
|
|
|
|
|
www.fullmm.com
Posts: 141
|
 |
« Reply #481 on: 23 Jul '08 - 09:07 » |
Quote
|
sorry for my repley , but last reply was of tomson . i have a question i want to use splitter of file but not work for encode togetTime = Bass.BASS_StreamCreateFile(item.Path, 0, 0, BASSFlag.BASS_DEFAULT); EncodeStream = Bass.BASS_StreamCreateFile(item.Path, Bass.BASS_ChannelSeconds2Bytes(togetTime, item.StartTime), Bass.BASS_ChannelSeconds2Bytes(togetTime, item.EndTime), BASSFlag.BASS_STREAM_DECODE);
|
|
|
|
|
Logged
|
|
|
|
|
radio42
Posts: 4012
|
 |
« Reply #482 on: 23 Jul '08 - 09:36 » |
Quote
|
Here comes some source code for: - recording from an input and feeding this to a mixer channel (full-duplex) - playback of some audio and feeding this to a mixer channel - setting up an encoder on the final mixer stream a) the main mixer channel (output) private BassAsioHandler _asioHandlerOut = null; ... BassAsio.BASS_ASIO_SetDevice(0); BassAsio.BASS_ASIO_Stop(); private int _mixerStream = 0; // setup asio _mixerStream = BassMix.BASS_Mixer_StreamCreate(44100, 2, BASSFlag.BASS_MIXER_RESUME | BASSFlag.BASS_MIXER_NONSTOP | BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE); _asioHandlerOut = new BassAsioHandler(0, 0, _mixerStream); if (!BassAsio.BASS_ASIO_IsStarted()) BassAsio.BASS_ASIO_Start(0); ... // now you can add any audio playback stream to the asio mixer like this // NOTE: 'mixerSource' can be any decoding bass stream here! BASSFlag flags = BASSFlag.BASS_MIXER_DOWNMIX | BASSFlag.BASS_MIXER_FILTER | BASSFlag.BASS_MIXER_BUFFER | BASSFlag.BASS_MIXER_NORAMPIN; BassMix.BASS_Mixer_StreamAddChannel(_mixerStream, mixerSource, flags);
b) The input recording from ASIO: private BassAsioHandler _asioHandlerIn = null; private int _recordStream = 0; ... // Init BassAsio.BASS_ASIO_SetDevice(0); BassAsio.BASS_ASIO_Stop(); _recordStream = 0; // setup asio _asioHandlerIn = new BassAsioHandler(true, 0, 0, 2, BASSASIOFormat.BASS_ASIO_FORMAT_FLOAT, 44100); _asioHandlerIn.UseInput = true; // fx recording stream _recordStream = _asioHandlerIn.InputChannel; if (!BassAsio.BASS_ASIO_IsStarted()) BassAsio.BASS_ASIO_Start(0); ... // now route the asio input to the asio output mixer for full duplex _asioHandlerIn.SetFullDuplex(0, BASSFlag.BASS_STREAM_DECODE, false); BASSFlag flags = BASSFlag.BASS_MIXER_DOWNMIX | BASSFlag.BASS_MIXER_FILTER | BASSFlag.BASS_MIXER_BUFFER | BASSFlag.BASS_MIXER_NORAMPIN; // here you add the full duplex channel as a new source to the mixer BassMix.BASS_Mixer_StreamAddChannel(_mixerStream, _asioHandlerIn.OutputChannel, flags);
c) setting up a broadcaster on the mixer (e.g. using LAME): BaseEncoder encoder = null; EncoderLAME lame = new EncoderLAME(_mixerStream); lame.LAME_Quality = EncoderLAME.LAMEQuality.Quality; lame.LAME_EnforceCBR = true; lame.LAME_UseVBR = false; lame.LAME_Bitrate = 128; lame.LAME_ABRBitrate = 0; encoder = lame;
StreamingServer server = null; SHOUTcast shout = new SHOUTcast(encoder, true); shout.Aim = "aim"; shout.Genre = "genre"; shout.Icq = "icq"; shout.Irc = "irc"; shout.Password = "password"; shout.PublicFlag = true; shout.ServerAddress = "address"; shout.ServerPort = 8000; shout.StationName = "stationName"; shout.Url = "stationUrl"; server = shout; server.SongTitle = "initialSongTitle";
BroadCast broadcast = new BroadCast(server); broadcast.AutoReconnect = true; broadcast.ReconnectTimeout = 5; broadcast.NotificationSupressDataSend = true; broadcast.AutoConnect();
|
|
|
|
|
Logged
|
|
|
|
|
radio42
Posts: 4012
|
 |
« Reply #483 on: 23 Jul '08 - 10:18 » |
Quote
|
Can you a bit more describe what you are trying to do with the 'splitter'?
|
|
|
|
|
Logged
|
|
|
|
|
www.fullmm.com
Posts: 141
|
 |
« Reply #484 on: 23 Jul '08 - 14:32 » |
Quote
|
Can you a bit more describe what you are trying to do with the 'splitter'? i want to encode just secends of file , for example i have a file which have 4:24 secends , and i try to encode file just between 20(start)-50(end) secends ; how can i do this. thx;
|
|
|
|
|
Logged
|
|
|
|
|
radio42
Posts: 4012
|
 |
« Reply #485 on: 23 Jul '08 - 15:11 » |
Quote
|
Take a look to the "BaseEncoder" class - it hosts a method called "EncodeFile", which allows you to only encode parts of the original file. The "BaseEncoder" class can be found in the Misc namespace and the documentation contains a lot of examples.
|
|
|
|
|
Logged
|
|
|
|
|
ken
Posts: 630
|
 |
« Reply #486 on: 23 Jul '08 - 18:01 » |
Quote
|
Here comes some source code for: - recording from an input and feeding this to a mixer channel (full-duplex) - playback of some audio and feeding this to a mixer channel - setting up an encoder on the final mixer stream
Yes close to same as I figure out. But the problem is that when I start my "monitor audio" (my Mic works with the BassMixer) my playback stop working.. I wan't both playback of MP3's and Live Mic input. Here is how i did: Init ASIO out and BASS + creating mixer
if(Bass.BASS_Init(0, 48000, 0, IntPtr.Zero, null)) { // init the winamp DSP plugin BassWaDsp.BASS_WADSP_Init(IntPtr.Zero); } else { System.Windows.MessageBox.Show("Bass_Init error!"); return;
}
_mixer = BassMix.BASS_Mixer_StreamCreate(44100, 2, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_MIXER_NONSTOP); if (_mixer == 0) { System.Windows.MessageBox.Show("Could not create mixer!"); Bass.BASS_Free(); return; }
if (_mixer != 0) _asioOut[0] = new BassAsioHandler(0, 0 , _mixer);
_asioOut[0].Start(0);
Starting "Live input" and add channel to the mixer public void MonitorStart() { _asioIn[0] = new BassAsioHandler(true, 0, 0, 2, BASSASIOFormat.BASS_ASIO_FORMAT_FLOAT, 48000); _asioIn[0].UseInput = true; _asioIn[0].SetFullDuplex(0, 0); //_asioIn[0].Start(0); _asioOut[0].StartFullDuplex(0); _MicChannel = _asioIn[0].OutputChannel; BassMix.BASS_Mixer_ChannelRemove(_MicChannel); BassMix.BASS_Mixer_StreamAddChannel(_mixer, _MicChannel, BASSFlag.BASS_MIXER_PAUSE | BASSFlag.BASS_MIXER_DOWNMIX); }
Stoping "live input" public void MonitorStop() { BassMix.BASS_Mixer_ChannelRemove(_MicChannel);
if (_asioIn[0] != null) { _asioIn[0].Stop(); _asioIn[0].Dispose(); _asioIn[0] = null; } }
And last adding a MP3 to the mixer (wish works just fine) BassMix.BASS_Mixer_ChannelRemove(_stream); Bass.BASS_StreamFree(_stream);
_stream = Bass.BASS_StreamCreateFile(CWmedia.Filename, 0L, 0L, BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE);
BassMix.BASS_Mixer_StreamAddChannel(_mixer, _stream, BASSFlag.BASS_MIXER_PAUSE | BASSFlag.BASS_MIXER_DOWNMIX);
Maybe I'm code blind, but I don't see how to do it..
|
|
|
|
« Last Edit: 23 Jul '08 - 18:04 by ken »
|
Logged
|
|
|
|
|
ken
Posts: 630
|
 |
« Reply #487 on: 23 Jul '08 - 19:09 » |
Quote
|
YES, I was blind... I missed: _asioIn[0].SetFullDuplex(0, BASSFlag.BASS_STREAM_DECODE, false);
Thanks, Bernd!
|
|
|
|
|
Logged
|
|
|
|
|
ken
Posts: 630
|
 |
« Reply #488 on: 24 Jul '08 - 13:44 » |
Quote
|
Next question...
Can I take a stereo input (from ASIO) and split it Left/Right into to streams, so I can use "Left" on one channel in my BassMixer, and "right" on another channel?
|
|
|
|
|
Logged
|
|
|
|
|
radio42
Posts: 4012
|
 |
« Reply #489 on: 24 Jul '08 - 15:21 » |
Quote
|
Sure, when you still want to use the BASS.NET "AsioHandler" you can create two instances of it. Today you are creating the AsioHandler with 2 channels. Now you create 2 recording (input) instances with only 1 channel. - One for the logical left channel (which is 1 ASIO channel) - Another one for the logical right channel (which is 1 ASIO channel) Note, that you need to specify the ASIO channels accordingly.
For the rest it is all the same and you can then feed the two independent "_asioIn.OutputChannel"s to your mixer independently or even to two different mixer channels.
|
|
|
|
|
Logged
|
|
|
|
|
whitingjon
Posts: 9
|
 |
« Reply #490 on: 24 Jul '08 - 15:40 » |
Quote
|
Question on the EncoderLame class. I am wondering why the -x is added to the command prompt automatically. Using that option, my files come out very bad. Removing that option (cut and pasting the command line, and running myself), it sounds fine.
I am simply trying to encode a wav file to an mp3. I cant just use LAME, because my WAV file is in CCITT encoding, and LAME doesnt seem to support that native. But, I can open it using Bass, then feed it to the encoder, and it seems to work fine. Also, in the future, I would love to add in wma support.
|
|
|
|
|
Logged
|
|
|
|
|
radio42
Posts: 4012
|
 |
« Reply #491 on: 24 Jul '08 - 16:31 » |
Quote
|
The "-x" forces byte swapping for LAME, since BASS by default sends little-endian and LAME uses big-endian by default. So in all my test this worked very nicely and I had never problems with this.
|
|
|
|
|
Logged
|
|
|
|
|
radio42
Posts: 4012
|
 |
« Reply #492 on: 24 Jul '08 - 17:02 » |
Quote
|
Hi Folks, in the latest LAME release (3.98) the folks have changed the default endian behavior of the encoder. So the "-x" flag which was used by the BASS.NET EncoderLAME class is no longer needed and actually needs to be removed. Here is an update: Lib only: www.un4seen.com/filez/4/Bass24.Net_pre.zip
|
|
|
|
|
Logged
|
|
|
|
|
ken
Posts: 630
|
 |
« Reply #493 on: 25 Jul '08 - 13:27 » |
Quote
|
Sure, when you still want to use the BASS.NET "AsioHandler" you can create two instances of it.
Works great, thanks! Can I somehow set bigger buffer on a "streamCreated" (MP3) played thro BASSmixer, with out loosing ASIO latency. Sometimes the MP3 "crackle" when playback (specialy if i'm in Windows Exporer opening folders, then it pops...) If increase the latency on my ASIO card to 512 or 1024 then it's sound ok, but I whant low latency for my LiveInputs via microphones. 
|
|
|
|
|
Logged
|
|
|
|
|
radio42
Posts: 4012
|
 |
« Reply #494 on: 25 Jul '08 - 15:28 » |
Quote
|
The AsioStart(x) parameter can be used. Currently it uses 0 which means the default buffer as set in the driver is used. However, increasing the Asio buffer means an increased latency.
BUT...there might be another problem related to ASIO (resp. low latancy) and .Net - which is the Garbage Collector! When the Garbage Collector starts (and you don't know exactly when this happens, as it can happen at any time) it suspends all threads which are being called in. E.g. an unmanaged method (in this case BASS) calls a method in the managed .Net world (e.g. a DSPPROC or ASIOPROC coded in C# or VB.Net) and at this time the GC is running the callback delegate will only return to the managed code once the GC has finished.
This is true for ALL BASS callbacks (like the ASIOPROC, DSPPROC, RECPROC, ENCODEPROC etc. etc.!!!) - meaning when the GC is running and a callback is invoked to a .Net method, this callback will ONLY return once the GC has finished doing it's job.
So the problem is now: If the GC run takes longer than your actual buffer you will hear a stuttering sound. I also noticed this with my application! Not only with BASSASIO, but also with normal BASS and setting the buffer to e.g. 20ms.
To test, if this is the case for you - just create a push button which explicitly calls "GC.Collect()" - if you hear a stuttering sound when clicking the button...you know why ;-)
So all depends on your application. If your application only uses a few objects, a GC run is normaly very quick - around 1 to 2 ms. This is sufficient even for an ASIO buffer having only 256 samples. However, the GC time increases as your application is growing. In my case - where I have a very rich UI - a GC run might even take up to 100 ms!
The good news is: there is a solution to the problem! The bad news is: the solution isn't such simple!
The only thing you can do, to be 100% sure, that the GC really nerver inerfears with any audio processing is to make sure, that you NEVER code any callback within .Net, but within managed code (e.g. C/C++).
So how should that really work out? Pertty "simple". With VisualStudio you are able to generate a so called "Mixed Mode" assembly. This is an assembly which hosts managed and unmanaged code in the same dll ! The trick is now to implement ALL your callbacks in native C/C++ - simply write a C++ class which basically only contains your specific callback implementation in C++. Now you can write a .Net wrapper (a so called proxy, at best in C#) which holds a pointer to your unmanaged class instance. Your app now only calls the wrapper class, which by itself invokes the related BASS method and hands over the pointer to the unmanaged callback implementation. By doing so you have made sure, that unmanaged BASS will only make callbacks to unmanaged code - and thus any GC runs leave the audio processing completely uneffected.
There is one good trick to see, if you did all correct: Write a .Net app and let some audio play. While playback set a breakpoint and make sure the VS Debugger is invoked during the playback. If you enter the breakpoint in the VS .Net debugger and your audio starts to stutter - then you will have the exact same problem if the GC is running. But if you enter the breakpoint in the VS .Net debugger and your audio continues to play just fine - then all is perfect!
Really so complex? Yes it is. And it has ONE more downside. You can not use all the ready-made and extended BASS.NET classes, like the AsioHandler anymore! Since these ready-made classes contain their own callbacks (i.e. the ready-made ASIOPROCs) which are all implemented in C# - meaning managed code. So you also would have to implement your own AsioHandler.
So there are ONLY two solutions to your problem I guess: a) make sure a GC run never takes too long (which is in some cases impossible). b) write your own "Mixed Mode" assemblies and wrap all callbacks into managed code.
So get a start with "Mixed Mode" assemblies: Just google and searching a little for "mixed mode assemblies" and you'll find a lot of code examples.
How did I solve the problem for my app? I have written my own Mixed Mode assembly! Once you get it (how to do it), it is really not hard and only takes a few hours. So all my code is 100% pure C# - except this little mixed mode wrapper, which only containing the callback implementations in C++ - which are anyhow very small in code size.
Why couldn't there be a BASS.NET version which already contains these 'mixed mode' stuff? Actually I tried to do so, but the problem is, that typically every user needs some specials in their callbacks. So every user would have to write it's own mixed mode assembly anyhow. That's why I decided to NOT do it - as it wouldn't give you any real benfit. Beside that it would restrict BASS.NET much more (no direct compact framework support, no linux (mono) support etc.) - as well as tons for new user questions - which I am unable to answer :-) So I guess it is really better to let BASS.NET as it is and leave it to the user to implement it's own mixed-mode stuff.
|
|
|
|
|
Logged
|
|
|
|
|
www.fullmm.com
Posts: 141
|
 |
« Reply #495 on: 27 Jul '08 - 11:16 » |
Quote
|
hello i want to record from mic , but when i dow that any sound which my computer plays record whit mic
how can i record just from mic
|
|
|
|
|
Logged
|
|
|
|
|
Chris
Posts: 1501
|
 |
« Reply #496 on: 27 Jul '08 - 12:07 » |
Quote
|
Hi You must set the Mic as Input Device Take alook in the Doku about BASS_RecordSetInput Cheers Chris
|
|
|
|
|
Logged
|
|
|
|
|
ken
Posts: 630
|
 |
« Reply #497 on: 27 Jul '08 - 14:58 » |
Quote
|
WOW... So I need to write all callbacks needed in C++ myself, ASIO, Encoder, SyncProc..? There goes all your nice functions I love (Asiohandler, encoder handler....)
Is the "mixed assemblies" like "unsafe" code?
I tried a button with GC.Collect, and when running under 512 sample I can somtimes here small "clicks", but not the break in sounds heard when I open a folder in Windows Explorer.
Another thing, I trided to set buffer with asio.Start() but get error if value is over 256 (and on 128 and 256 playback is fast and funny sounding, this also depending on my soundcards settings for latency) tesed in your "Simple ASIO" app.
I have to set lateny in my soundcard's control panel. I have a "ESI MAYA 44" soundcard. on Vista 32bit.
|
|
|
|
|
Logged
|
|
|
|
|
radio42
Posts: 4012
|
 |
« Reply #498 on: 27 Jul '08 - 17:31 » |
Quote
|
Yes, some ASIO driver only allow the bufer setting in their contro panel.
So if you don't have the breaking sound at 512 samples when you call GC.Collect - then your GC runs fast enough and there is no need to implement all callbacks yourself into a C++ function. So I guess your stuttering sound when opening a folder in the windows explorer must be related to something else - does this also happen with other demo apps? And no, mixed mode assemblies are normal assemblies hosting pure .Ner code as well as pure C/C++ code - so it has nothing to do with 'unsafe' code blocks in C#.
|
|
|
|
|
Logged
|
|
|
|
|
ken
Posts: 630
|
 |
« Reply #499 on: 27 Jul '08 - 19:07 » |
Quote
|
So I guess your stuttering sound when opening a folder in the windows explorer must be related to something else - does this also happen with other demo apps? Yes same with your "SimpleAsio" example (with 512 in buffer set on the card, and 0 in the SimpleAsio app). Also same with Bassasio own examples. Just wanna know why and if I should care about it. It "pops" in the sound everytime I open a foilder.
|
|
|
|
|
Logged
|
|
|
|
|