简体   繁体   中英

Playing Audio in .Net / C#

I'm an experienced MFC programmer of many years, who for the more recent years has been developing commercial apps in Objective C for Mac and iOS - I'm trying to get up to speed with.Net and C# (as I'm soon going to be required to convert one of my commercial apps from Mac to PC).

I've now worked my way through a couple of books and as an exercise to get more familiar with.Net (and C#) I've decided to have a go at converting one of my none commercial apps to.Net as a learning exercise and all is going well (interface is working, data structures all good) but I need to be able to play audio.

My Mac app generates audio from a series of mathematical formula - imagine a wave generator - not quite the same but similar. On the Mac I generate the audio as 16 bit signed raw audio, use Core Audio to setup audio output routing and then get a callback whenever a new buffer of audio is required for the audio routing (so I can generate the audio on the fly).

I need to do the same on the PC. Unfortunately I find MSDN documentation to be a case of "Can't see the wood for the trees" as there is such a vast amount of documentation. I can find classes that will let me load and play mp3/wav etc files, but I need to generate the audio realtime. Can anyone point me in the right direction to find something that will allow me to fill buffers on the fly as it plays them?

Thx

I have used this sample in several projects with good results. It is basically a.Net wrapper for Windows Waveform Audio API using P/Invoke . Other choices:

I have created a class that can play audio given Stream derivate as an input. So if you are able to pack your sound-generator into the Stream compatible interface, it could be suitable for you.

How I did it - I used unmanaged waveOut* methods from old Windows multimedia API, and handled the playback from there.

Other options - that I am aware of - use waveOut directly, from this: http://windowsmedianet.sourceforge.net/ or write your own DirectShow source filter, but that might be too complicated, since it has to be written in c++.

If you are interested in giving my component a try, I can make it available to you at no charge, since I need it beta tested (I only used it in several of my projects).

EDIT:

Since there are 6 upvotes to the question, I am offering my component free of charge (if you find useful) here: http://dl.dropbox.com/u/10020780/SimpleAudioPlayer.zip

Maybe you can reflect on it:)

I use Audiere to accomplish this and find it works very well.

It's a C++ lib really, but there are a set of bindings available for C#.

For more info, see the question I asked .

You should have a look at FMOD which allows this kind of operation and much more. It is also cross platform which can be interested if you are also working on a mac.

Alvas.Audio has 3 audio players: Player

        player.FileName = "123.mp3";
        player.Play();

PlayerEx

        public static void TestPlayerEx()
        {
            PlayerEx plex = new PlayerEx();
            plex.Done += new PlayerEx.DoneEventHandler(plex_Done);
            Mp3Reader mr = new Mp3Reader(File.OpenRead("in.mp3"));
            IntPtr format = mr.ReadFormat();
            byte[] data = mr.ReadData();
            mr.Close();
            plex.OpenPlayer(format);
            plex.AddData(data);
            plex.StartPlay();
        }

        static void plex_Done(object sender, DoneEventArgs e)
        {
            if (e.IsEndPlaying)
            {
                ((PlayerEx)sender).ClosePlayer();
            }
        }

and RecordPlayer

        public static void TestRecordPlayer()
        {
            RecordPlayer rp = new RecordPlayer();
            rp.PropertyChanged += new PropertyChangedEventHandler(rp_PropertyChanged);
            rp.Open(new Mp3Reader(File.OpenRead("in.mp3")));
            rp.Play();
        }

        static void rp_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case RecordPlayer.StateProperty:
                    RecordPlayer rp = ((RecordPlayer)sender);
                    if (rp.State == DeviceState.Stopped)
                    {
                        rp.Close();
                    }
                    break;
            }
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM