21 May '13 - 15:46 *
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] 2  All
  Reply  |  Print  
Author Topic: Playing Split Stereo Files Suggestions...  (Read 1722 times)
BaseHead
Posts: 91


« on: 13 Jul '11 - 02:29 »
Reply with quoteQuote

So, I was wondering if anyone has tackled this yet before I start to code it.
I want to play two separate mono files that are filename.L.wav and filename.R.wav as one Interleaved Stereo file.

Any suggestions of the best way to do this?

thx in advance!

Steve

C# .NET



Logged
Ian @ un4seen
Administrator
Posts: 15254


« Reply #1 on: 13 Jul '11 - 15:12 »
Reply with quoteQuote

The easiest way to do it would be with the the BASSmix add-on, ie. create a stereo mixer and plug the 2 mono files into it. That could look something like this...

left=BASS_StreamCreateFile(FALSE, "filename.L.wav", 0, 0, BASS_STREAM_DECODE|BASS_SAMPLE_FLOAT); // create decoding channel from left file
right=BASS_StreamCreateFile(FALSE, "filename.R.wav", 0, 0, BASS_STREAM_DECODE|BASS_SAMPLE_FLOAT); // create decoding channel from right file
BASS_CHANNELINFO ci;
BASS_ChannelGetInfo(left, &ci);
mixer=BASS_Mixer_StreamCreate(ci.freq, 2, BASS_MIXER_END); // create stereo mixer with same sample rate
BASS_Mixer_StreamAddChannel(mixer, left, BASS_SPEAKER_FRONTLEFT); // add the left source to the mix (on the left)
BASS_Mixer_StreamAddChannel(mixer, right, BASS_SPEAKER_FRONTRIGHT); // add the right source to the mix (on the right)
BASS_ChannelPlay(mixer, FALSE); // start playing

Please see the documentation for details on the aforementioned functions. Note if you want to replay the mix, you would need to rewind the sources, like this...

BASS_Mixer_ChannelSetPosition(left, 0, BASS_POS_BYTE); // rewind the left
BASS_Mixer_ChannelSetPosition(right, 0, BASS_POS_BYTE); // rewind the right
BASS_ChannelPlay(mixer, TRUE); // restart the mixer
Logged
BaseHead
Posts: 91


« Reply #2 on: 14 Jul '11 - 00:45 »
Reply with quoteQuote

Thx IAN!

I've been trying to avoid using BASSMix since I read an issue with latency and other issues, but it might not be avoidable for much longer.

Is it gonna add lag from the moment I hit play till when I hear the audio compared to not using BASSMix?

My Mac coder had it hooked up a long time ago in our OSX version and everything felt sluggish so I had him yank it out in the end so I've been trying to avoid it in the .NET version since it seems like lots of work to start using it and have to go back if performance suffers

great support as always!!

Steve
Logged
radio42
Posts: 4012


« Reply #3 on: 14 Jul '11 - 08:39 »
Reply with quoteQuote

Normally using BASSmix shouldn't add any latency or increase the performance needs.
There is of course a slight increase of CPU usage, but not even really noticable.
So I am using BASSmix heavily and haven't found any real issues with it.
Logged
Ian @ un4seen
Administrator
Posts: 15254


« Reply #4 on: 14 Jul '11 - 15:02 »
Reply with quoteQuote

The mixer shouldn't add any latency in this case, where the mixer is only playing the 2 mono sources.

Using a mixer can add latency when it is playing other stuff and a source is added to the mix, ie. the new source won't be heard until after the mixer's already buffered output. That additional latency can be reduced by lowering the mixer's playback buffer size via the BASS_CONFIG_BUFFER option (and BASS_CONFIG_UPDATEPERIOD). If the mixer doesn't have a playback buffer (via the BASS_STREAM_DECODE flag), then it won't add any latency; that would be the case when using ASIO or WASAPI output, for example.
Logged
BaseHead
Posts: 91


« Reply #5 on: 15 Jul '11 - 20:01 »
Reply with quoteQuote

Thx for the info guys!!
I'll try and play with it this weekend.
If you know of any threads or tutorials you can point me to to help understand hooking up BASSMIX (or any other addon for that matter) please pass it along.
I'm still trying to grasp the concept stil...hehehe

I loaded up the demo project for BASSMIX about 6 months back, but if I remember correctly it didn't do  a whole lot compared to the other examples.
I was expecting a mixer with sliders and pans.
I'll check it out again later to see if I was missing something.

thx!

Steve

Logged
BaseHead
Posts: 91


« Reply #6 on: 16 Jul '11 - 07:03 »
Reply with quoteQuote

ooohh...I found the docs in the help file explaining fairly well....Cool

s>
Logged
BaseHead
Posts: 91


« Reply #7 on: 17 Jul '11 - 11:11 »
Reply with quoteQuote

Ian/Bernd...

So I got it rocking in my C# test app all good!

But once I put it in my main app it's playing all crazy. 
It speeds up and slows down, stutters, pauses randomly and double triggers playback at the head.

It almost sounds like it time compressed heavily at times.
Songs will have the correct pitch but be 4x shorter as if you are fast forwarding on a DVD.

If I remove these flags ( BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT) then it plays correct but doesn't really seem like it doing it's job and seems bypassed then.

Anything I should be looking for you can think that might cause this you can think of or a way to fix this?

Thx as always guys!

Steve
Logged
Ian @ un4seen
Administrator
Posts: 15254


« Reply #8 on: 18 Jul '11 - 16:08 »
Reply with quoteQuote

Are you calling BASS_ChannelGetData/Level on the mono streams that are plugged into the mixer? Those functions will decode data from the streams, which will then not be available to the mixer, resulting in the playback skipping and sounding fast. If you would like to get data from the streams without affecting the mixer, you can instead add the BASS_MIXER_BUFFER flag to the BASS_Mixer_StreamAddChannel calls and replace the BASS_ChannelGetData/Level calls with BASS_Mixer_ChannelGetData/Level.
Logged
BaseHead
Posts: 91


« Reply #9 on: 19 Jul '11 - 01:44 »
Reply with quoteQuote

Ok, I tried that and it didn't work but I only tried on the GetData  since I didn't see the /Level part
Thankfull I saw you post to Robin on the same issue.

I was my PeakMeterDisplay code that was freaking it out that was doing a BASS_ChannelGetLevel call
I changed those to BassMix.BASS_Mixer_ChannelGetLevel and all good now with that!  Cool

Here's is the corrected method if it will help anyone in C#

 private void UpdatePeakMeterDisplay(object sender, EventArgs e)
        {
            float[] level = new float[2]; // dealing with stereo
            if (BassMix.BASS_Mixer_ChannelGetLevel(_SoundPlayer.Stream, level)) //Changed for BassMix
            {
                if (BassMix.BASS_Mixer_ChannelGetLevel(_SoundPlayer.Stream, level)) //Changed for BassMix
                {
                    float left = level[0]; // the left level
                    float right = level[1]; // the right level
                    this.meterLeft.Dispatcher.BeginInvoke((Action)delegate()
                    {
                        this.meterLeft.Value = left * 100;
                    });

                    this.meterRight.Dispatcher.BeginInvoke((Action)delegate()
                    {
                        this.meterRight.Value = right * 100;
                    });
                }

            }

        }


One more thing Ian.  Using BASSMIX I get many files double triggering the first 100-200ms at the head.
We make an audio database for sound effects so users are auditioning many files by down arrowing down a list and right now doubles are being played all the time when clicking thru the list with BASSMIX in the chain.

This actually might have been the problem I saw a year ago when my Mac coder popped it into the OSX version that made me tell him to yank it out cuz it was driving me nuts and responsiveness went to hell.......hehehe

I'm playing with the  BASS_CONFIG_BUFFER option now but doesn't seem to help.
Anything under 500ms plays choppy and anything up to 5000 still double triggers the head of the file
Any other settings to play with to fix this?

Awesome job with tech support as always!

Steve
Logged
Ian @ un4seen
Administrator
Posts: 15254


« Reply #10 on: 19 Jul '11 - 14:41 »
Reply with quoteQuote

That's strange. From your description of "double triggering", it sounds like it could be old data repeating? If so, perhaps it's an output buffer underrun (resulting in old data repeating) caused by the mixer taking too long to generate the mix. One way a mixer can be delayed is by mixtime syncs set on it or its sources; do you have any of those, and if so, what are they doing? If the problem only ever occurs when adding a new file to the mix, please also confirm how you are doing that.
Logged
BaseHead
Posts: 91


« Reply #11 on: 19 Jul '11 - 20:46 »
Reply with quoteQuote

Hey!
well, not old data but new data technically.
I'd consider old data from the previous file played.

Better explanation:
If I click on a new sound in the list it plays the 1st 100-200ms of the file and then goes back to the top of the same exact file and plays the whole thing top to bottom then.
More like a false start

No mixtime syncs that I know about that I put in.
It's a very basic setup as far as BASSMIX goes so far with basically only your instructions you have given me up to now.

Steve



Logged
Ian @ un4seen
Administrator
Posts: 15254


« Reply #12 on: 20 Jul '11 - 15:21 »
Reply with quoteQuote

I should clarify, when I said "old data", I meant around 0.5s old, not previous track old Smiley ... When the mixer (or any other playing stream) takes too long to produce its data, the playback will loop in the meantime (on Windows), so the last 0.5s (or whatever BASS_CONFIG_BUFFER has been set to) will be heard again.

Please post the code that you're using to start playback of a source. Perhaps you're doing something like this...

BASS_Mixer_StreamAddChannel(mixer, source, 0); // add a source to the mix
BASS_ChannelSetPosition(source, 0, BASS_POS_BYTE); // rewind it

That could explain what you're reporting, ie. the mixer starts playing the source, and then the source is rewound and the start is heard again. The calls should be the other way round, ie. prepare the source (position/volume/etc) and then add it to the mix.
Logged
BaseHead
Posts: 91


« Reply #13 on: 21 Jul '11 - 10:47 »
Reply with quoteQuote

Ok, figured it out... Smiley
It was some Pause/Resume code that was messing it all up that works fine without BASSMIX
So that is all good now, but now my whole program feels sluggish now graphically.
A fairly big graphics performance hit it seems
The playhead that scrolls over the waveform is way chunky now and same with the Spectrum Meters that jjohnston makes.
Basically, all the graphics that update on a timer like TimeElapsed/Remaining are all moving in slow motion now...... Sad
Kind of like it's displaying at 1/4 the frame rate compared to not using BASSMIX


Any ideas on that one?

thx!

Steve
Logged
Ian @ un4seen
Administrator
Posts: 15254


« Reply #14 on: 21 Jul '11 - 15:41 »
Reply with quoteQuote

Please confirm what the "playhead" position is based on. If it's using BASS_ChannelGetPosition on a mixer source, try using BASS_Mixer_ChannelGetPosition instead; the former will give the decoding position, while the latter will give the position that's currently being heard from the mixer.
Logged
BaseHead
Posts: 91


« Reply #15 on: 22 Jul '11 - 10:27 »
Reply with quoteQuote

Hey Ian!
I was using BASS_Mixer_ChannelGetPosition last night with no luck but then today is started working.
I did a complete rebuild so maybe that helped......Cool
It was 4am when I quit so who knows, but that doesn't matter since it's working now......hehe

Last question for this thread:
once I switched to BassMix I have to add a *2 to most of  my set position code for when I click on the waveform to relocate to get to the correct position all of a sudden

Before BassMix
BassMix.BASS_Mixer_ChannelSetPosition(_SoundPlayer.Stream, posDown);

After BassMix
BassMix.BASS_Mixer_ChannelSetPosition(_SoundPlayer.Stream, posDown * 2);

Any ideas what that is all about?

cya!

Steve


Logged
Ian @ un4seen
Administrator
Posts: 15254


« Reply #16 on: 22 Jul '11 - 16:56 »
Reply with quoteQuote

Good to hear it's working now, mostly Smiley

Regarding the last question, that looks like it could be related to the BASS_SAMPLE_FLOAT flag, ie. a 32-bit floating-point sample is twice the size of a 16-bit sample. How are you calculating the "posDown" value?
Logged
BaseHead
Posts: 91


« Reply #17 on: 22 Jul '11 - 21:01 »
Reply with quoteQuote

Here's some of it

int clkUp = Convert.ToInt32(e.GetPosition(grdWaveform).X);  //Gets mouse up click position
 int width = Convert.ToInt32(grdWaveform.ActualWidth);
 if (clkUp < 0) { clkUp = 0; } //Limits the left size so it can't go beyond 0
 long posUP = WF2.GetBytePositionFromX(clkUp, width, _zoomStart, _zoomEnd);
 long posDown = (WF2.GetBytePositionFromX(clkDown, width, _zoomStart, _zoomEnd)) ;

And I do have that flag on in my Sound Player code
Stream = Bass.BASS_StreamCreateFile(path, 0, 0, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT);

If I kill it then everything is back to normal (well mostly)
is that flag needed for anything other then audition quality?
We make a audio database and might be fine to play in 16 bit since it's just a quick audition tool anyway

thx!


Steve
Logged
Ian @ un4seen
Administrator
Posts: 15254


« Reply #18 on: 25 Jul '11 - 17:31 »
Reply with quoteQuote

It looks like the "GetBytePositionFromX" function is where the calculation is done, so please post that too.
Logged
BaseHead
Posts: 91


« Reply #19 on: 26 Jul '11 - 04:45 »
Reply with quoteQuote

Hey!

That function is in Bass.NET
Un4seen.Bass.Misc.Waveform
public long GetBytePositionFromX(int x, int graphicsWidth, int frameStart, int frameEnd);

BTW....that function call only happens one other time in the code and only in a special case.

Do I need this FLOAT flag if we are cool with audition quality at 16bit?

cya!

s>


Logged
Pages: [1] 2  All
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.18 | SMF © 2013, Simple Machines