Author Topic: BASS for WinCE  (Read 237980 times)

Ian @ un4seen

  • Administrator
  • Posts: 20437
Re: BASS for WinCE
« Reply #100 on: 7 Aug '09 - 16:03 »
Good to hear that you got it working after the addition of ACM. I'll see if it is possible to make the ACM support optional, so that BASS will still load without it.

Regarding DX8 effects, I'm afraid they are not included in WinCE. So you would indeed need to implement your own equalizer via a DSP function. You can find some equalizer source code here...

   www.musicdsp.org

Note that it should be implemented in integer/fixed-point for decent performance, as floating-point is very slow without an FPU.

Ian @ un4seen

  • Administrator
  • Posts: 20437
Re: BASS for WinCE
« Reply #101 on: 11 Aug '09 - 14:16 »
An updated BASS build is now in the CE package (see 1st post), which should work without ACM support being present in the OS (BASS will just disable its ACM support in that case). Please report any problems with it.

cablehead

  • Posts: 315
Re: BASS for WinCE
« Reply #102 on: 11 Aug '09 - 21:01 »
Can anyone convert the C spectrum.exe to C#?

Simon chen

  • Guest
Re: BASS for WinCE
« Reply #103 on: 12 Aug '09 - 12:05 »
@cablehead
it's easy to implement the spectrum use the bass.net for ce, this is a piece of example code:
            Graphics g = Graphics.FromImage(pictureBox.Image);
            Rectangle rect = new Rectangle(0, 0, WIDTH, HEIGHT);
            SolidBrush brush = new SolidBrush(Color.Black);
            g.FillRectangle(brush, rect);
            brush.Dispose();
            brush = new SolidBrush(Color.Green);
            int bandWidth = WIDTH / BAND_CONST;//BAND_CONST = 28
            int b0 = 0;
            int band, height;
            Random rnd1 = new Random();
            StringBuilder sb = new StringBuilder();
           

            for (band = 0; band < BAND_CONST; band++)
            {
                float sum = 0;
                int sc, b1 = (int)System.Math.Pow(2, band * 10.0 / (BAND_CONST - 1));
                if (b1 > 1023) b1 = 1023;
                if (b1 <= b0) b1 = b0 + 1; // make sure it uses at least 1 FFT bin
                sc = 10 + b1 - b0;
                for (; b0 < b1; b0++)
                {
                    sum += FFTData[1 + b0];
                }

                height = (int)(System.Math.Sqrt(sum / System.Math.Log10(sc)) * 1.5 * HEIGHT) - 4; // scale it
                if (height> HEIGHT)
                {
                    height = HEIGHT;
                }

                g.FillRectangle(brush, band * bandWidth, HEIGHT - height, bandWidth - 1, height);
            }

            brush.Dispose();
            g.Dispose();
the code show the Spectrum to pictureBox componet. i only implement the case specmode==1(logarithmic, acumulate & average bins).
the other case can translate into CSharp in the same method. i'm not use CreateDIBSection to deal bmp, because it quick enough to me, if you want to use it, use DllImport to import it.

Simon chen

  • Guest
Re: BASS for WinCE
« Reply #104 on: 12 Aug '09 - 12:40 »
@IVan

thank you. i had find a equalizer source code, it work well in my PC, but too slowly to run in my wince device. i'm afraid that it's impossible to implement the equalizer quickly for me. is it possible to upgrade the directx to some new version to use BASS_ChannelSetFX correctly?

another problem, i writen a piece of code in my program to show spectrum:
   if (BASS_ChannelIsActive(stream) == BASS_ACTIVE_PLAYING)
   {
      CurrentTime = BASS_ChannelBytes2Seconds(stream, BASS_ChannelGetPosition(stream, BASS_POS_BYTE));
      CString PlayTime = FormatTime(CurrentTime) + " / " + FormatTime(TotalTime);
      SetWindowText(SongName + " - " + PlayTime);
      
      HDC dc;
      int x,y;
      DWORD result;
      CString msg;
      if (-1 == (result = BASS_ChannelGetData(stream, FFTData, BASS_DATA_FFT2048)))
      {
         return;
      }
      
      int b0=0;
      float sum;
      int sc,b1;
      memset(specbuf,0,SPECWIDTH*SPECHEIGHT);
#define BANDS 28
      for (x=0;x<BANDS;x++) {
         sum=0;
         b1=(int)pow(2,x*10.0/(BANDS-1));
         if (b1>1023) b1=1023;
         if (b1<=b0) b1=b0+1; // make sure it uses at least 1 FFT bin
         sc=10+b1-b0;
         for (;b0<b1;b0++)
         {
            sum+=FFTData[1+b0];
         }
         sum *= 1e38f;
         y=(int)(sqrt(sum/log10(sc))*1.7*SPECHEIGHT)-4; // scale it
         if (y>SPECHEIGHT) y=SPECHEIGHT; // cap it
         while (--y>=0)
         {
            memset(specbuf+y*SPECWIDTH+x*(SPECWIDTH/BANDS),y+1,SPECWIDTH/BANDS-2); // draw bar
         }
      }
      dc=::GetDC(m_Picture.GetSafeHwnd());
      BitBlt(dc,0,0,SPECWIDTH,SPECHEIGHT,specdc,0,0,SRCCOPY);
      ::ReleaseDC(m_Picture.GetSafeHwnd(), dc);
this code is modified from spectrum.c in bass package.  it's nessary to add sum *= 1e38f to show spectrum in my ce device, or else it didn't show correct.
but it show the spectrum correct without the (sum *= 1e38f;)statement when run it in my PC. why the return FFTData from BASS_ChannelGetData() function is different between XP and CE?(ce:about 1e-41,xp:about 1e-3?), the 1e38f is got from tries.

Ian @ un4seen

  • Administrator
  • Posts: 20437
Re: BASS for WinCE
« Reply #105 on: 12 Aug '09 - 16:04 »
thank you. i had find a equalizer source code, it work well in my PC, but too slowly to run in my wince device. i'm afraid that it's impossible to implement the equalizer quickly for me. is it possible to upgrade the directx to some new version to use BASS_ChannelSetFX correctly?

CE can support some DirectX components, but not fully (I think they are just emulated using other APIs) and unfortunately I don't think the DX8 effects are one of the supported things.

Did you implement your equalizer using integer/fixed-point math? Floating-point will be very slow, but I think the CPU usage of an integer/fixed-point EQ should be within reason.

this code is modified from spectrum.c in bass package.  it's nessary to add sum *= 1e38f to show spectrum in my ce device, or else it didn't show correct.
but it show the spectrum correct without the (sum *= 1e38f;)statement when run it in my PC. why the return FFTData from BASS_ChannelGetData() function is different between XP and CE?(ce:about 1e-41,xp:about 1e-3?), the 1e38f is got from tries.

That looks like you have taken the Win32 SPECTRUM example as a starting point, rather than the WinCE version of it? In the CE version, BASS_ChannelGetData gives 8.24 fixed-point data rather than floating-point.

radio42

  • Posts: 4576
Re: BASS for WinCE
« Reply #106 on: 12 Aug '09 - 18:00 »
Here comes the new BASS.NET CE version (for the .Net CompactFramework 2.0):
v2.4.0.9:
www.un4seen.com/filez/4/Bass24.Net_compact.zip

It now also supports the BASSenc add-on as well as the Encoder framework.
Let me know what you find...

cablehead

  • Posts: 315
Re: BASS for WinCE
« Reply #107 on: 15 Aug '09 - 17:18 »
Simon...What is FFTData in your example?

Simon chen

  • Guest
Re: BASS for WinCE
« Reply #108 on: 17 Aug '09 - 02:48 »
cablehead

        float[] FFTData = new float[1024];
        int length = Un4seen.Bass.Bass.BASS_ChannelGetData(handle, FFTData, (int)Un4seen.Bass.BASSData.BASS_DATA_FFT2048);
        if (length <= 0)
        {
            return;
        }

Simon chen

  • Guest
Re: BASS for WinCE
« Reply #109 on: 17 Aug '09 - 03:26 »
Ivan

I have modified my equalizer using 32 bit fixed-point integer math, it brought a significant improvement in playback speed, I estimate that it increased nearly 10 times. but ... the speed is still not fast enough, it have clear pause. i thought that it's difficult to implement it on wince.

gregory

  • Guest
Re: BASS for WinCE
« Reply #110 on: 18 Aug '09 - 17:58 »
Hi ! I'd like to develop a very useful program for my online station Vombat Radio - and i think we need a Win CE version of Bass.dll . Can anyone help me ? My email address is : vombatradio@gmail.com

cablehead

  • Posts: 315
Re: BASS for WinCE
« Reply #111 on: 18 Aug '09 - 20:44 »
Simon:

Your using-
 Graphics g = Graphics.FromImage(pictureBox.Image);
 
What are you using for the initail image?

Its null...

simon.chen

  • Posts: 6
Re: BASS for WinCE
« Reply #112 on: 19 Aug '09 - 02:25 »
@cablehead

add following code after InitializeComponent():
            pictureBox.Height = HEIGHT;
            pictureBox.Width = WIDTH;
            pictureBox.Image = new Bitmap(WIDTH, HEIGHT);
            BassNet.Registration("emailaddress", "xxxxxxxx");
            if ((Bass.BASS_GetVersion() >> 16) != Bass.BASSVERSION)
            {
                MessageBox.Show("Error version of 'Bass.dll' ");
            }

            if (!Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, this.Handle))
            {
                MessageBox.Show("Can't initialize device");
            }

or check up it before use:
if (pictureBox.Image == null)
{
    pictureBox.Image = new Bitmap(WIDTH, HEIGHT);
}
Graphics g = Graphics.FromImage(pictureBox.Image);

hc_mark

  • Guest
Re: BASS for WinCE
« Reply #113 on: 19 Aug '09 - 07:25 »
Hi! I am currently making a wince application that records voice input. I am using Bass.Net_compact and I am able to record and save it as wav file. However, I would like my recorded wav file to be encoded to mp3. Is this possible for WINCE?

Ian @ un4seen

  • Administrator
  • Posts: 20437
Re: BASS for WinCE
« Reply #114 on: 19 Aug '09 - 15:55 »
I have modified my equalizer using 32 bit fixed-point integer math, it brought a significant improvement in playback speed, I estimate that it increased nearly 10 times. but ... the speed is still not fast enough, it have clear pause. i thought that it's difficult to implement it on wince.

How many bands were you using? Perhaps that could be reduced, eg. just 3 bands (low/mid/high).

Anyway, I guess EQ will be a pretty common requirement, so I'll see if BASS can be made to emulate the BASS_FX_DX8_PARAMEQ effect on WinCE.

Hi ! I'd like to develop a very useful program for my online station Vombat Radio - and i think we need a Win CE version of Bass.dll . Can anyone help me ? My email address is : vombatradio@gmail.com

You can find the WinCE BASS stuff in the 1st post of this thread.

Hi! I am currently making a wince application that records voice input. I am using Bass.Net_compact and I am able to record and save it as wav file. However, I would like my recorded wav file to be encoded to mp3. Is this possible for WINCE?

I'm not sure. I don't think there are any command-line encoders for WinCE, but I guess there may be 3rd-party ACM codecs that'll do MP3 encoding. If so, they could be used via the BASSenc add-on, eg. the BASS_Encode_StartACMFile function. And if not ACM codecs, then perhaps there are MP3 encoding libraries, which could be used to encode the recorded data (eg. in the RECORDPROC callback function).

cablehead

  • Posts: 315
Re: BASS for WinCE
« Reply #115 on: 19 Aug '09 - 16:12 »
Simon...Thanks for the help..

The following code in a timer...creates the fill black rectangle...but nothing else.
No Color.green at all:

I create the stream with just the AUTOFREE flag.

private void timerpectrum_Tick(object sender, EventArgs e)
        {
            var WIDTH = pictureBoxASpectrum.Width;
            var HEIGHT = pictureBoxASpectrum.Height;
            const int BAND_CONST = 28;
            float[] FFTData = new float[1024];
            
            int length = Bass.BASS_ChannelGetData(stream, FFTData, (int)Un4seen.Bass.BASSData.BASS_DATA_FFT2048);
            if (length <= 0)
            {
                return;
            }
            if (pictureBoxASpectrum.Image == null)
            {
                pictureBoxASpectrum.Image = new Bitmap(WIDTH, HEIGHT);
            }
                      
            Graphics g = Graphics.FromImage(pictureBoxASpectrum.Image);
            Rectangle rect = new Rectangle(0, 0, WIDTH, HEIGHT);
            SolidBrush brush = new SolidBrush(Color.Black);
            g.FillRectangle(brush, rect);
            brush.Dispose();
            brush = new SolidBrush(Color.Green);
            int bandWidth = WIDTH / BAND_CONST;//BAND_CONST = 28
            int b0 = 0;
            int band, height;
          
            for (band = 0; band < BAND_CONST; band++)
            {
                float sum = 0;
                int sc, b1 = (int)System.Math.Pow(2, band * 10.0 / (BAND_CONST - 1));
                if (b1 > 1023) b1 = 1023;
                if (b1 <= b0) b1 = b0 + 1; // make sure it uses at least 1 FFT bin
                sc = 10 + b1 - b0;
                for (; b0 < b1; b0++)
                {
                    sum += FFTData[1 + b0];
                  
                }

                height = (int)(System.Math.Sqrt(sum / System.Math.Log10(sc)) * 1.5 * HEIGHT) - 4; // scale it
                if (height > HEIGHT)
                {
                    height = HEIGHT;
                }

                g.FillRectangle(brush, band * bandWidth, HEIGHT - height, bandWidth - 1, height);
            }

            brush.Dispose();
            g.Dispose();

        }
« Last Edit: 19 Aug '09 - 19:10 by cablehead »

simon.chen

  • Posts: 6
Re: BASS for WinCE
« Reply #116 on: 20 Aug '09 - 02:54 »
@cablehead

you can reference  the c++ code i post to Ivan before, the reason is that i have taken the Win32 SPECTRUM example as a starting point(i test it on pc first, so...).
If you are running it on pc you will get the correct results. if you are running it on ce device, a lazy way is to add following code (red color)
                for (; b0 < b1; b0++)
                {
                    sum += FFTData[1 + b0];
                  
                }
                sum *= 1e38f;
                height = (int)(System.Math.Sqrt(sum / System.Math.Log10(sc)) * 1.5 * HEIGHT) - 4;
but the correct way is taken the Wince SPECTRUM example as a starting point.
           int[] FFTData = new int[1024];
           ...
           ...
            for (band = 0; band < BAND_CONST; band++)
            {
                int sum = 0;
                int sc, b1 = (int)System.Math.Pow(2, band * 9.0 / (BAND_CONST - 1));
                if (b1 > 1023) b1 = 1023;
                if (b1 <= b0) b1 = b0 + 1; // make sure it uses at least 1 FFT bin
                sc = 10 + b1 - b0;
                for (; b0 < b1; b0++) sum += FFTData[1 + b0];
                height = (int)(System.Math.Sqrt(sum / (float)(1 << 24) / System.Math.Log10(sc)) * 1.7 * HEIGHT) - 4; // scale it
                if (height > HEIGHT) height = HEIGHT; // cap it
                g.FillRectangle(brush, band * bandWidth, HEIGHT - height, bandWidth - 1, height);
            }
enjoy it.
BTW: maybe you can make FFTData as a member variable of your form class, it doesn't need to new it in timer event function.
« Last Edit: 20 Aug '09 - 03:09 by simon.chen »

Ian @ un4seen

  • Administrator
  • Posts: 20437
Re: BASS for WinCE
« Reply #117 on: 20 Aug '09 - 14:59 »
An update is now in the CE package (see 1st post), including support for the BASS_FX_DX8_PARAMEQ effect. An FXTEST example has also been added to test it.

BASSenc has also been updated to work without ACM support being present in the OS (like BASS was recently).

simon.chen

  • Posts: 6
Re: BASS for WinCE
« Reply #118 on: 21 Aug '09 - 03:06 »
An update is now in the CE package (see 1st post), including support for the BASS_FX_DX8_PARAMEQ effect. An FXTEST example has also been added to test it.

BASSenc has also been updated to work without ACM support being present in the OS (like BASS was recently).

Yeah, It does work.

hc_dondon

  • Guest
Re: BASS for WinCE
« Reply #119 on: 25 Aug '09 - 13:40 »
How can i play mp3 via memory stream.
can you check my code pls.
 
FileStream fs = new FileStream(AFileName, FileMode.Open);
byte[] b = new byte[(int)fs.Length];
fs.Read(b, 0, (int)b.Length);
fs.Close();
IntPtr pval = Marshal.AllocHGlobal(b.Length);
try
{
 Marshal.Copy(b, 0, pval, (int)b.Length);
  Bass.BASS_StreamFree(playBackStream);
  playBackStream = Bass.BASS_StreamCreateFile(pval, 0, 0, BASSFlag.BASS_UNICODE); //BASS_UNICODE
}
finally
{
Marshal.FreeHGlobal(pval);
}

playBackStream returns -1 Am i missing something here.

thanks

radio42

  • Posts: 4576
Re: BASS for WinCE
« Reply #120 on: 25 Aug '09 - 14:53 »
Yes, please check the sample as provided in the BASS.NET docs!!!

Code: [Select]
private GCHandle _hGCFile;
...
// open a file
FileStream fs = File.OpenRead( "test.mp3" );
// get the legth of the file
long length = fs.Length;
// create the buffer which will keep the file in memory
byte[] buffer = new byte[length];
// read the file into the buffer
fs.Read(buffer, 0, length);
// buffer is filled, file can be closed
fs.Close();

// now create a pinned handle, so that the Garbage Collector will not move this object
_hGCFile = GCHandle.Alloc( buffer, GCHandleType.Pinned );
// create the stream (AddrOfPinnedObject delivers the necessary IntPtr)
int stream = Bass.BASS_StreamCreateFile(_hGCFile.AddrOfPinnedObject(),
                  0L, length, BASSFlag.BASS_SAMPLE_FLOAT);

if (stream != 0 && Bass.BASS_ChannelPlay(stream, false) )
{
    // playing...
}
else
{
    Console.WriteLine("Error = {0}", Bass.BASS_ErrorGetCode());
}
...
// when playback has ended and the pinned object is not needed anymore,
// we need to free the handle!
// Note: calling this method to early will crash the application,
// since the buffer would be stolen from BASS while still playing!
_hGCFile.Free();

hc_dondon

  • Guest
Re: BASS for WinCE
« Reply #121 on: 25 Aug '09 - 23:31 »
@radio24, i will check again my code and will use this one.
do you know of an encoder that converts wav to mp3 or  wav to wma?
we are pretty new to wince development, this is painless in win32 but not in wince.  :'(

hc_dondon

  • Guest
Re: BASS for WinCE
« Reply #122 on: 26 Aug '09 - 02:30 »
   private void SetFileName(string AFileName)
        {
            FFileName = AFileName;           
            //Open file
            FileStream fs = File.OpenRead(AFileName);               
            //get length of the file
            long length = fs.Length;
            //create memory buffer
            byte[] buffer = new byte[length];           
            fs.Read(buffer, 0, (int)length);
            fs.Close();                       
           
            if (this.GetState() == 1) this.Stop();           
            Bass.BASS_StreamFree(playBackStream);
            // now create a pinned handle, so that the Garbage Collector will not move this object
            _hGCFile = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            // create the stream (AddrOfPinnedObject delivers the necessary IntPtr)
            playBackStream = Bass.BASS_StreamCreateFile(_hGCFile.AddrOfPinnedObject(), 0L, length, BASSFlag.BASS_SAMPLE_FLOAT);
            //playBackStream = Bass.BASS_StreamCreateFile(pval, 0, 0, BASSFlag.BASS_UNICODE); //BASS_UNICODE
            FPLength = Bass.BASS_ChannelGetLength(playBackStream, BASSMode.BASS_POS_BYTES);

            FTotalTime = Decimal.Truncate(Convert.ToDecimal(Bass.BASS_ChannelBytes2Seconds(playBackStream, FPLength) * 1000));
            FStopPosition = Convert.ToInt32(FTotalTime);
            //_hGCFile.Free();       
}

playbackstream returns -1


radio42

  • Posts: 4576
Re: BASS for WinCE
« Reply #123 on: 26 Aug '09 - 07:18 »
What error code do you get when you call BASS_ErrorGetCode right after the BASS_StreamCreateFile call?

hc_dondon

  • Guest
Re: BASS for WinCE
« Reply #124 on: 27 Aug '09 - 02:12 »
it worked, i checked the code and it returns invalid format. I just changed it to BASSFlag.BASS_UNICODE..

playBackStream = Bass.BASS_StreamCreateFile(_hGCFile.AddrOfPinnedObject(), 0L, length, BASSFlag.BASS_UNICODE);

thanks radio..