0
0

Hi all,

I have been looking around this forum, but could not find answer to the following question. How to use DSP callback functionality in C#? I get a NotSupported failure each time. Below I have some testcode, which does run on a WinXP machine, but not on a PocketPC. Can someone help?? Is this NotSupported by the CompactFramework on the PocketPC, or is this NotSupported in the fmodce.dll (or something alike).

(Sorry for long listing 😳 )

[code:3sgau885]
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.Text;
using System.Runtime.InteropServices;

namespace CSHARP_SmartDeviceApplication
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button btnInit;
private System.Windows.Forms.Button btnPlay;
private System.Windows.Forms.Button btnStop;
private System.Windows.Forms.Button btnClose;
private System.Windows.Forms.MainMenu mainMenu1;

    public Form1()
    {
        //
        // Required for Windows Form Designer support
        //
        InitializeComponent();

        //
        // TODO: Add any constructor code after InitializeComponent call
        //
    }
    /// &lt;summary&gt;
    /// Clean up any resources being used.
    /// &lt;/summary&gt;
    protected override void Dispose( bool disposing )
    {
        base.Dispose( disposing );
    }
    #region Windows Form Designer generated code
    /// &lt;summary&gt;
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// &lt;/summary&gt;
    private void InitializeComponent()
    {
        this.mainMenu1 = new System.Windows.Forms.MainMenu();
        this.btnInit = new System.Windows.Forms.Button();
        this.btnPlay = new System.Windows.Forms.Button();
        this.btnStop = new System.Windows.Forms.Button();
        this.btnClose = new System.Windows.Forms.Button();
        // 
        // btnInit
        // 
        this.btnInit.Location = new System.Drawing.Point(72, 32);
        this.btnInit.Text = &quot;init&quot;;
        this.btnInit.Click += new System.EventHandler(this.btnInit_Click);
        // 
        // btnPlay
        // 
        this.btnPlay.Location = new System.Drawing.Point(72, 88);
        this.btnPlay.Text = &quot;Play&quot;;
        this.btnPlay.Click += new System.EventHandler(this.btnPlay_Click);
        // 
        // btnStop
        // 
        this.btnStop.Location = new System.Drawing.Point(72, 136);
        this.btnStop.Text = &quot;Stop&quot;;
        this.btnStop.Click += new System.EventHandler(this.button1_Click);
        // 
        // btnClose
        // 
        this.btnClose.Location = new System.Drawing.Point(72, 192);
        this.btnClose.Text = &quot;Close&quot;;
        this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
        // 
        // Form1
        // 
        this.Controls.Add(this.btnClose);
        this.Controls.Add(this.btnStop);
        this.Controls.Add(this.btnPlay);
        this.Controls.Add(this.btnInit);
        this.Menu = this.mainMenu1;
        this.Text = &quot;Form1&quot;;

    }
    #endregion

    /// &lt;summary&gt;
    /// The main entry point for the application.
    /// &lt;/summary&gt;

    static void Main() 
    {
        Application.Run(new Form1());
    }

region FMOD definitions

    [DllImport(&quot;fmodce.dll&quot;, SetLastError=true, CharSet=CharSet.Unicode, CallingConvention=CallingConvention.Winapi)]
    public static extern bool FSOUND_Init(int mixrate , int maxsoftwarechannels , int flags );

    [DllImport(&quot;fmodce.dll&quot;, SetLastError=true, CharSet=CharSet.Unicode, CallingConvention=CallingConvention.Winapi)]
    public static extern IntPtr FSOUND_Stream_Open(IntPtr data , int mode , int offset , int length );

    [DllImport(&quot;fmodce.dll&quot;, SetLastError=true, CharSet=CharSet.Unicode, CallingConvention=CallingConvention.Winapi)]
    public static extern int FSOUND_Stream_Play(int channel , IntPtr fstream);

    [DllImport(&quot;fmodce.dll&quot;, SetLastError=true, CharSet=CharSet.Unicode, CallingConvention=CallingConvention.Winapi)]
    public static extern bool FSOUND_Stream_Stop(IntPtr fstream );

    [DllImport(&quot;fmodce.dll&quot;, SetLastError=true, CharSet=CharSet.Unicode, CallingConvention=CallingConvention.Winapi)]
    public static extern void FSOUND_Close();

    public delegate IntPtr DSPCALLBACK(
    IntPtr originalbuffer ,
    IntPtr newbuffer,
    int length, 
    IntPtr userdata 
    );

    [DllImport(&quot;fmodce.dll&quot;, SetLastError=true, CharSet=CharSet.Unicode, CallingConvention=CallingConvention.Winapi)]
    public static extern IntPtr FSOUND_DSP_Create(
        DSPCALLBACK callback ,
        int priority,
        IntPtr userdata
    );

    [DllImport(&quot;fmodce.dll&quot;, SetLastError=true, CharSet=CharSet.Unicode, CallingConvention=CallingConvention.Winapi)]
    public static extern void FSOUND_DSP_SetActive(IntPtr unit, bool active );

    #endregion

    private IntPtr soundStream = IntPtr.Zero;
    private IntPtr soundHandle = IntPtr.Zero;

    /// TODO: change here the correct paths to the mp3 file
    // for WinCE or PocketPC
    //private String currentSoundTrack = &quot;\\My Documents\\test.mp3&quot;;
    // for Win200, WinXP, and similar
    //private String currentSoundTrack = &quot;C:\\test.mp3&quot;;

    public static IntPtr myDSPCallbackHandler(
        IntPtr originalbuffer ,
        IntPtr newbuffer,
        int length, 
        IntPtr userdata)
    {
        return newbuffer;
    }

    private void btnInit_Click(object sender, System.EventArgs e)
    {
        bool b = FSOUND_Init(44100, 16, 0);

        DSPCALLBACK dspcb = new DSPCALLBACK(myDSPCallbackHandler);

        try 
        {
            IntPtr dspunit = FSOUND_DSP_Create(dspcb, 302, IntPtr.Zero); // Error location
            FSOUND_DSP_SetActive(dspunit, true);
        }
        catch (Exception exception)
        {
            String s = exception.ToString();    // exception = NotSupported
        }
        finally
        {
        }

        //create a handle to hold the track stream - REPLACE HERE fmod_getStream BY fmod_getStream_New TO TRY WITHOUT THE AddrOfPinnedObject BUG FIX !
        soundStream = fmod_getStream(currentSoundTrack);

        //open the stream in Normal mode, which is combination of Mono sound, 16 bits, Signed
        soundHandle = FSOUND_Stream_Open(soundStream, 0x10 | 0x20 | 0x100, 0, 0);
    }

    private void btnPlay_Click(object sender, System.EventArgs e)
    {
        //and play from there
        FSOUND_Stream_Play(0, soundHandle);
    }

    private void button1_Click(object sender, System.EventArgs e)
    {
        FSOUND_Stream_Stop(soundHandle);
    }

    private void btnClose_Click(object sender, System.EventArgs e)
    {
        FSOUND_Close();
    }

    private IntPtr fmod_getStream(String filename) 
    {
        byte[] filenames = Encoding.Default.GetBytes(filename);
        GCHandle hfile = GCHandle.Alloc(filenames, GCHandleType.Pinned);

        IntPtr result = IntPtr.Zero;

        //if the .NET CF version is 1.x, then we add 4 bytes to the address of the pinned object, 
        //because AddrOfPinnedObject returns the address of the object shifted of 4 bytes, which corresponds to the storage space of the pointer itself
        //the bug is only in CF 1.x so this bug-fix needs to be conditional
        if (( Environment.OSVersion.Platform == PlatformID.WinCE ) &amp;&amp; ( Environment.Version.Major == 1 ))
        {
            result = new IntPtr(hfile.AddrOfPinnedObject().ToInt32() + 4);
        }
        else
        {
            result = hfile.AddrOfPinnedObject();
        }

        if ( hfile.IsAllocated)
            hfile.Free();

        return result;
    }
}

}
[/code:3sgau885]

  • You must to post comments
0
0

I found it. This is really NOT SUPPORTED by the .NET Compact Framework.

For those with similar problems: I have solved it by implementing the callback in a Embedded C++ library, and initialising it from C#, by a call RegisterPlugin() and SetActive(). Now the callback is running in C++ and the rest of the application in C#

Regards,Arjan

  • You must to post comments
Showing 1 result
Your Answer

Please first to submit.