Пример #1
0
        private void JingleInit(string filename)
        {
            FMOD.Sound tempSound = null;
            thisLock = new Object();
            // Retrieve information about sound
            FMOD.RESULT result = system.createSound(filename, (FMOD.MODE._2D | FMOD.MODE.SOFTWARE), ref tempSound);
            ErrorCheck(result);

            FMOD.SOUND_TYPE   soundType   = (FMOD.SOUND_TYPE) 0;
            FMOD.SOUND_FORMAT soundFormat = (FMOD.SOUND_FORMAT) 0;

            int tempBits     = 0,
                tempChannels = 0,
                tempPriority = 0;

            uint tempPcm = 0;

            float tempFrequency = 0.0f,
                  tempPan       = 0.0f,
                  tempVolume    = 0.0f;

            result = tempSound.getFormat(ref soundType, ref soundFormat, ref tempChannels, ref tempBits);
            ErrorCheck(result);

            result = tempSound.getDefaults(ref tempFrequency, ref tempVolume, ref tempPan, ref tempPriority);
            ErrorCheck(result);

            result = tempSound.getLength(ref tempPcm, FMOD.TIMEUNIT.PCM);
            ErrorCheck(result);

            // Fill sound parameters
            ChannelCount = tempChannels;
            Frequency    = (int)tempFrequency;
            pcm          = tempPcm;
            bits         = tempBits;

            // Obtain Raw PCM data from sound
            GetRawData(tempSound, tempChannels, tempBits, tempPcm);


            // Release temp sound instance
            tempSound.release();
            tempSound = null;


            FMOD.CREATESOUNDEXINFO exInfo = new FMOD.CREATESOUNDEXINFO();
            exInfo.cbsize           = Marshal.SizeOf(exInfo);
            exInfo.length           = (uint)(pcm * sizeof(short));
            exInfo.numchannels      = ChannelCount;
            exInfo.format           = FMOD.SOUND_FORMAT.PCM16;
            exInfo.defaultfrequency = (int)Frequency;
            // Create a stream from obtained data

            result = system.createStream(SoundDataBuffer.Buffer, (FMOD.MODE.OPENMEMORY | FMOD.MODE.OPENRAW), ref exInfo, ref sounds);
            ErrorCheck(result);
        } // loading jingle
        private void timer_Tick(object sender, System.EventArgs e)
        {
            FMOD.RESULT    result;
            FMOD.OPENSTATE openstate = 0;

            if (soundcreated)
            {
                uint percentbuffered = 0;
                bool starving        = false;
                bool busy            = false;

                result = sound.getOpenState(ref openstate, ref percentbuffered, ref starving, ref busy);
                ERRCHECK(result);

                if (openstate == FMOD.OPENSTATE.READY && channel == null)
                {
                    result = system.playSound(FMOD.CHANNELINDEX.FREE, sound, false, ref channel);
                    ERRCHECK(result);
                }
            }

            if (channel != null)
            {
                uint ms          = 0;
                bool playing     = false;
                bool paused      = false;
                int  tagsupdated = 0;
                int  numtags     = 0;

                result = sound.getNumTags(ref numtags, ref tagsupdated);
                ERRCHECK(result);

                if (tagsupdated != 0)
                {
                    for (;;)
                    {
                        FMOD.TAG tag = new FMOD.TAG();

                        if (sound.getTag(null, -1, ref tag) != FMOD.RESULT.OK)
                        {
                            break;
                        }

                        if (tag.datatype == FMOD.TAGDATATYPE.STRING)
                        {
                            FMOD.SOUND_FORMAT format = FMOD.SOUND_FORMAT.NONE;
                            int channels             = 0;
                            int bits = 0;

                            sound.getFormat(ref gSoundType, ref format, ref channels, ref bits);

                            if (tag.name == "ARTIST")
                            {
                                if (Marshal.PtrToStringAnsi(tag.data) != gCurrentTrackArtist)
                                {
                                    gCurrentTrackArtist = Marshal.PtrToStringAnsi(tag.data);
                                    gUpdateFileName     = true;
                                }
                            }
                            if (tag.name == "TITLE")
                            {
                                if (Marshal.PtrToStringAnsi(tag.data) != gCurrentTrackTitle)
                                {
                                    gCurrentTrackTitle = Marshal.PtrToStringAnsi(tag.data);
                                    gUpdateFileName    = true;
                                }
                            }
                            break;
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                result = channel.isPlaying(ref playing);
                if (result != FMOD.RESULT.OK || !playing)
                {
                    sound.release();
                    sound   = null;
                    channel = null;
                }
                else
                {
                    result = channel.getPaused(ref paused);
                    ERRCHECK(result);
                    result = channel.getPosition(ref ms, FMOD.TIMEUNIT.MS);
                    ERRCHECK(result);

                    statusBar.Text = "Time " + (ms / 1000 / 60) + ":" + (ms / 1000 % 60) + ":" + (ms / 10 % 100) + (paused ? " Paused " : playing ? " Playing" : " Stopped");
                }
            }

            if (sound != null)
            {
                uint percentbuffered = 0;
                bool starving        = false;
                bool busy            = false;

                sound.getOpenState(ref openstate, ref percentbuffered, ref starving, ref busy);

                if (openstate == FMOD.OPENSTATE.ERROR)
                {
                    sound.release();
                    sound   = null;
                    channel = null;
                }
            }

            if (openstate == FMOD.OPENSTATE.ERROR)
            {
                statusBar.Text = "Error occurred or stream ended.  Restarting stream..";
                result         = system.createSound(url, (FMOD.MODE.HARDWARE | FMOD.MODE._2D | FMOD.MODE.CREATESTREAM | FMOD.MODE.NONBLOCKING), ref exinfo, ref sound);
                ERRCHECK(result);
            }

            if (system != null)
            {
                system.update();
            }
        }
Пример #3
0
        public static void WriteWavHeader(FileStream stream, FMOD.Sound sound, int length, Object usingFmod)
        {
            FMOD.SOUND_TYPE   type = FMOD.SOUND_TYPE.UNKNOWN;
            FMOD.SOUND_FORMAT format = FMOD.SOUND_FORMAT.NONE;
            int   channels = 0, bits = 0, temp1 = 0;
            float rate = 0.0f;
            float temp = 0.0f;

            if (sound == null)
            {
                return;
            }
            lock (usingFmod) {
                sound.getFormat(ref type, ref format, ref channels, ref bits);
                sound.getDefaults(ref rate, ref temp, ref temp, ref temp1);
            }

            log.Info("WaveWriter.WriteWavHeader: sound format: dataLength " + length + ", type " + type + ", format " + format +
                     ", channels " + channels + ", bits " + bits + ", rate " + rate);

            stream.Seek(0, SeekOrigin.Begin);

            FmtChunk  fmtChunk  = new FmtChunk();
            DataChunk dataChunk = new DataChunk();
            WavHeader wavHeader = new WavHeader();
            RiffChunk riffChunk = new RiffChunk();

            fmtChunk.chunk           = new RiffChunk();
            fmtChunk.chunk.id        = new char[4];
            fmtChunk.chunk.id[0]     = 'f';
            fmtChunk.chunk.id[1]     = 'm';
            fmtChunk.chunk.id[2]     = 't';
            fmtChunk.chunk.id[3]     = ' ';
            fmtChunk.chunk.size      = Marshal.SizeOf(fmtChunk) - Marshal.SizeOf(riffChunk);
            fmtChunk.wFormatTag      = 1;
            fmtChunk.nChannels       = (ushort)channels;
            fmtChunk.nSamplesPerSec  = (uint)rate;
            fmtChunk.nAvgBytesPerSec = (uint)(rate * channels * bits / 8);
            fmtChunk.nBlockAlign     = (ushort)(1 * channels * bits / 8);
            fmtChunk.wBitsPerSample  = (ushort)bits;

            dataChunk.chunk       = new RiffChunk();
            dataChunk.chunk.id    = new char[4];
            dataChunk.chunk.id[0] = 'd';
            dataChunk.chunk.id[1] = 'a';
            dataChunk.chunk.id[2] = 't';
            dataChunk.chunk.id[3] = 'a';
            dataChunk.chunk.size  = (int)length;

            wavHeader.chunk       = new RiffChunk();
            wavHeader.chunk.id    = new char[4];
            wavHeader.chunk.id[0] = 'R';
            wavHeader.chunk.id[1] = 'I';
            wavHeader.chunk.id[2] = 'F';
            wavHeader.chunk.id[3] = 'F';
            wavHeader.chunk.size  = (int)(Marshal.SizeOf(fmtChunk) + Marshal.SizeOf(riffChunk) + length);
            wavHeader.rifftype    = new char[4];
            wavHeader.rifftype[0] = 'W';
            wavHeader.rifftype[1] = 'A';
            wavHeader.rifftype[2] = 'V';
            wavHeader.rifftype[3] = 'E';

            /*
             *  Write out the WAV header.
             */
            IntPtr wavHeaderPtr = Marshal.AllocHGlobal(Marshal.SizeOf(wavHeader));
            IntPtr fmtChunkPtr  = Marshal.AllocHGlobal(Marshal.SizeOf(fmtChunk));
            IntPtr dataChunkPtr = Marshal.AllocHGlobal(Marshal.SizeOf(dataChunk));

            byte   [] wavHeaderBytes = new byte[Marshal.SizeOf(wavHeader)];
            byte   [] fmtChunkBytes  = new byte[Marshal.SizeOf(fmtChunk)];
            byte   [] dataChunkBytes = new byte[Marshal.SizeOf(dataChunk)];

            Marshal.StructureToPtr(wavHeader, wavHeaderPtr, false);
            Marshal.Copy(wavHeaderPtr, wavHeaderBytes, 0, Marshal.SizeOf(wavHeader));

            Marshal.StructureToPtr(fmtChunk, fmtChunkPtr, false);
            Marshal.Copy(fmtChunkPtr, fmtChunkBytes, 0, Marshal.SizeOf(fmtChunk));

            Marshal.StructureToPtr(dataChunk, dataChunkPtr, false);
            Marshal.Copy(dataChunkPtr, dataChunkBytes, 0, Marshal.SizeOf(dataChunk));

            stream.Write(wavHeaderBytes, 0, Marshal.SizeOf(wavHeader));
            stream.Write(fmtChunkBytes, 0, Marshal.SizeOf(fmtChunk));
            stream.Write(dataChunkBytes, 0, Marshal.SizeOf(dataChunk));
        }
Пример #4
0
        private void SaveToWav()
        {
            FileStream fs = null;
            int        channels = 0, bits = 0;
            float      rate = 0;
            IntPtr     ptr1 = new IntPtr(), ptr2 = new IntPtr();
            uint       lenbytes = 0, len1 = 0, len2 = 0;

            FMOD.SOUND_TYPE   type   = FMOD.SOUND_TYPE.WAV;
            FMOD.SOUND_FORMAT format = FMOD.SOUND_FORMAT.NONE;
            int   temp1 = 0;
            float temp3 = 0;

            if (sound == null)
            {
                return;
            }

            sound.getFormat(ref type, ref format, ref channels, ref bits);
            sound.getDefaults(ref rate, ref temp3, ref temp3, ref temp1);
            sound.getLength(ref lenbytes, FMOD.TIMEUNIT.PCMBYTES);

            FmtChunk  fmtChunk  = new FmtChunk();
            DataChunk dataChunk = new DataChunk();
            WavHeader wavHeader = new WavHeader();
            RiffChunk riffChunk = new RiffChunk();

            fmtChunk.chunk           = new RiffChunk();
            fmtChunk.chunk.id        = new char[4];
            fmtChunk.chunk.id[0]     = 'f';
            fmtChunk.chunk.id[1]     = 'm';
            fmtChunk.chunk.id[2]     = 't';
            fmtChunk.chunk.id[3]     = ' ';
            fmtChunk.chunk.size      = Marshal.SizeOf(fmtChunk) - Marshal.SizeOf(riffChunk);
            fmtChunk.wFormatTag      = 1;
            fmtChunk.nChannels       = (ushort)channels;
            fmtChunk.nSamplesPerSec  = (uint)rate;
            fmtChunk.nAvgBytesPerSec = (uint)(rate * channels * bits / 8);
            fmtChunk.nBlockAlign     = (ushort)(1 * channels * bits / 8);
            fmtChunk.wBitsPerSample  = (ushort)bits;

            dataChunk.chunk       = new RiffChunk();
            dataChunk.chunk.id    = new char[4];
            dataChunk.chunk.id[0] = 'd';
            dataChunk.chunk.id[1] = 'a';
            dataChunk.chunk.id[2] = 't';
            dataChunk.chunk.id[3] = 'a';
            dataChunk.chunk.size  = (int)lenbytes;

            wavHeader.chunk       = new RiffChunk();
            wavHeader.chunk.id    = new char[4];
            wavHeader.chunk.id[0] = 'R';
            wavHeader.chunk.id[1] = 'I';
            wavHeader.chunk.id[2] = 'F';
            wavHeader.chunk.id[3] = 'F';
            wavHeader.chunk.size  = (int)(Marshal.SizeOf(fmtChunk) + Marshal.SizeOf(riffChunk) + lenbytes);
            wavHeader.rifftype    = new char[4];
            wavHeader.rifftype[0] = 'W';
            wavHeader.rifftype[1] = 'A';
            wavHeader.rifftype[2] = 'V';
            wavHeader.rifftype[3] = 'E';

            fs = new FileStream("record.wav", FileMode.Create, FileAccess.Write);

            /*
             *  Write out the WAV header.
             */
            IntPtr wavHeaderPtr = Marshal.AllocHGlobal(Marshal.SizeOf(wavHeader));
            IntPtr fmtChunkPtr  = Marshal.AllocHGlobal(Marshal.SizeOf(fmtChunk));
            IntPtr dataChunkPtr = Marshal.AllocHGlobal(Marshal.SizeOf(dataChunk));

            byte   [] wavHeaderBytes = new byte[Marshal.SizeOf(wavHeader)];
            byte   [] fmtChunkBytes  = new byte[Marshal.SizeOf(fmtChunk)];
            byte   [] dataChunkBytes = new byte[Marshal.SizeOf(dataChunk)];

            Marshal.StructureToPtr(wavHeader, wavHeaderPtr, false);
            Marshal.Copy(wavHeaderPtr, wavHeaderBytes, 0, Marshal.SizeOf(wavHeader));

            Marshal.StructureToPtr(fmtChunk, fmtChunkPtr, false);
            Marshal.Copy(fmtChunkPtr, fmtChunkBytes, 0, Marshal.SizeOf(fmtChunk));

            Marshal.StructureToPtr(dataChunk, dataChunkPtr, false);
            Marshal.Copy(dataChunkPtr, dataChunkBytes, 0, Marshal.SizeOf(dataChunk));

            fs.Write(wavHeaderBytes, 0, Marshal.SizeOf(wavHeader));
            fs.Write(fmtChunkBytes, 0, Marshal.SizeOf(fmtChunk));
            fs.Write(dataChunkBytes, 0, Marshal.SizeOf(dataChunk));

            /*
             *  Lock the sound to get access to the raw data.
             */
            sound.@lock(0, lenbytes, ref ptr1, ref ptr2, ref len1, ref len2);

            /*
             *  Write it to disk.
             */
            byte [] rawdata = new byte[len1];

            Marshal.Copy(ptr1, rawdata, 0, (int)len1);

            fs.Write(rawdata, 0, (int)len1);

            /*
             *  Unlock the sound to allow FMOD to use it again.
             */
            sound.unlock(ptr1, ptr2, len1, len2);

            fs.Close();

            MessageBox.Show("Written to record.wav");
        }
Пример #5
0
        IEnumerator StreamCR()
        {
            /*
             * FMOD seems to like this
             */
            yield return(new WaitForSeconds(2f));

            this.streamCaught = false;
            this.trackChanged = false;

            for (;;)
            {
                if (this.isPaused)
                {
                    yield return(null);
                }

                if (this.finished)
                {
                    this.Stop();
                    yield break;
                }

                result = system.update();
                ERRCHECK(result, "system.update", false);

                result = sound.getOpenState(out openstate, out bufferFillPercentage, out starving, out deviceBusy);
                ERRCHECK(result, "sound.getOpenState", false);

                LOG(LogLevel.DEBUG, "Stream open state: {0}, buffer fill {1} starving {2} networkBusy {3}", openstate, bufferFillPercentage, starving, deviceBusy);

                if (!this.streamCaught)
                {
                    int c = 0;
                    do
                    {
                        result = system.update();
                        ERRCHECK(result, "system.update", false);

                        result = sound.getOpenState(out openstate, out bufferFillPercentage, out starving, out deviceBusy);
                        ERRCHECK(result, "sound.getOpenState", false);

                        LOG(LogLevel.DEBUG, "Stream open state: {0}, buffer fill {1} starving {2} networkBusy {3}", openstate, bufferFillPercentage, starving, deviceBusy);

                        if (result == FMOD.RESULT.OK && openstate == FMOD.OPENSTATE.READY)
                        {
                            /*
                             * stream caught
                             */
                            FMOD.SOUND_TYPE   _streamType;
                            FMOD.SOUND_FORMAT _streamFormat;
                            int _streamBits;

                            result = sound.getFormat(out _streamType, out _streamFormat, out this.streamChannels, out _streamBits);
                            ERRCHECK(result, "sound.getFormat");

                            float freq; int prio;
                            result = sound.getDefaults(out freq, out prio);
                            ERRCHECK(result, "sound.getDefaults");

                            LOG(LogLevel.INFO, "Stream format {0} {1} {2} channels {3} bits {4} samplerate", _streamType, _streamFormat, this.streamChannels, _streamBits, freq);

                            if (this is AudioStream)
                            {
                                // compensate for the stream samplerate
                                this.GetComponent <AudioSource>().pitch = ((float)(freq * this.streamChannels) / (float)(AudioSettings.outputSampleRate * (int)AudioSettings.speakerMode));
                            }

                            this.StreamStarting((int)freq);

                            this.streamCaught = true;

                            this.isPlaying = true;

                            if (this.OnPlaybackStarted != null)
                            {
                                this.OnPlaybackStarted.Invoke(this.gameObjectName);
                            }

                            break;
                        }
                        else
                        {
                            /*
                             * Unable to stream
                             */
                            if (++c > 60)
                            {
                                if (this.url.StartsWith("http"))
                                {
                                    LOG(LogLevel.ERROR, "Can't start playback. Please make sure that correct audio type of stream is selected and network is reachable.");
#if UNITY_EDITOR
                                    LOG(LogLevel.ERROR, "If everything seems to be ok, restarting the editor often helps while having trouble connecting to especially OGG streams.");
#endif
                                }
                                else
                                {
                                    LOG(LogLevel.ERROR, "Can't start playback. Unrecognized audio type.");
                                }

                                this.Stop();

                                yield break;
                            }
                        }

                        yield return(new WaitForSeconds(0.1f));
                    } while (result != FMOD.RESULT.OK || openstate != FMOD.OPENSTATE.READY);
                }

                if (this.StreamStarving())
                {
                    LOG(LogLevel.WARNING, "Stream buffer starving - stopping playback");

                    this.Stop();

                    yield break;
                }

                FMOD.TAG streamTag;

                /*
                 *  Read any tags that have arrived, this could happen if a radio station switches
                 *  to a new song.
                 */
                while (sound.getTag(null, -1, out streamTag) == FMOD.RESULT.OK)
                {
                    if (!this.trackChanged)
                    {
                        this.tags         = new string[tagcount];
                        this.tagindex     = 0;
                        this.trackChanged = true;
                    }

                    if (streamTag.datatype == FMOD.TAGDATATYPE.STRING)
                    {
                        string tagData = Marshal.PtrToStringAnsi(streamTag.data, (int)streamTag.datalen);
                        tags[tagindex] = string.Format("{0} = {1}", streamTag.name, tagData);
                        tagindex       = (tagindex + 1) % tagcount;
                    }
                    else if (streamTag.type == FMOD.TAGTYPE.FMOD)
                    {
                        /* When a song changes, the samplerate may also change, so compensate here. */
                        if (streamTag.name == "Sample Rate Change")
                        {
                            // TODO: actual float and samplerate change test - is there a way to test this ?

                            float defFrequency;
                            int   defPriority;
                            result = sound.getDefaults(out defFrequency, out defPriority);
                            ERRCHECK(result, "sound.getDefaults");

                            LOG(LogLevel.INFO, "Stream samplerate change from {0}", defFrequency);

                            // float frequency = *((float*)streamTag.data);
                            float[] frequency = new float[1];
                            Marshal.Copy(streamTag.data, frequency, 0, sizeof(float));

                            LOG(LogLevel.INFO, "Stream samplerate change to {0}", frequency[0]);

                            result = sound.setDefaults(frequency[0], defPriority);
                            ERRCHECK(result, "sound.setDefaults");

                            /*
                             * need to restart audio when changing samplerate..
                             */
                            if (this is AudioStream)
                            {
                                // compensate for the stream samplerate
                                this.GetComponent <AudioSource>().pitch = ((float)(frequency[0] * this.streamChannels) / (float)(AudioSettings.outputSampleRate * (int)AudioSettings.speakerMode));
                            }
                        }
                    }
                }

                if (this.trackChanged)
                {
                    // TODO: track changed event
                    LOG(LogLevel.INFO, "Track changed {0}", this.tags[0]); // print tags[0] for info only - might be anything
                    this.trackChanged = false;
                }

                yield return(null);
            }
        }