Exemplo n.º 1
0
        public override void Perform(AudioData audio, PreviewImageQuery query)
        {
            int     desiredWidth  = query.DesiredWidth;
            int     desiredHeight = query.DesiredHeight;
            int     oggHash       = audio.OggVorbisData.GetCombinedHashCode();
            int     oggLen        = audio.OggVorbisData.Length;
            PcmData pcm           = OggVorbis.LoadChunkFromMemory(audio.OggVorbisData, 500000);

            short[] sdata  = pcm.data;
            short   maxVal = 1;

            for (int i = 0; i < pcm.dataLength; i++)
            {
                maxVal = Math.Max(maxVal, Math.Abs(pcm.data[i]));
            }

            Bitmap    result        = new Bitmap(desiredWidth, desiredHeight);
            int       channelLength = pcm.dataLength / pcm.channelCount;
            int       yMid          = result.Height / 2;
            int       stepWidth     = (channelLength / (2 * result.Width)) - 1;
            const int samples       = 10;

            using (Graphics g = Graphics.FromImage(result))
            {
                Color baseColor = ExtMethodsColor.ColorFromHSV(
                    (float)(oggHash % 90) * (float)(oggLen % 4) / 360.0f,
                    0.5f,
                    1f);
                Pen linePen = new Pen(Color.FromArgb(MathF.RoundToInt(255.0f / MathF.Pow((float)samples, 0.65f)), baseColor));
                g.Clear(Color.Transparent);
                for (int x = 0; x < result.Width; x++)
                {
                    float invMaxVal      = 2.0f / ((float)maxVal + (float)short.MaxValue);
                    float timePercentage = (float)x / (float)result.Width;
                    int   i = MathF.RoundToInt(timePercentage * channelLength);
                    float left;
                    float right;
                    short channel1;
                    short channel2;

                    for (int s = 0; s <= samples; s++)
                    {
                        int offset = stepWidth * s / samples;
                        channel1 = sdata[(i + offset) * pcm.channelCount + 0];
                        channel2 = sdata[(i + offset) * pcm.channelCount + 1];
                        left     = (float)Math.Abs(channel1) * invMaxVal;
                        right    = (float)Math.Abs(channel2) * invMaxVal;
                        g.DrawLine(linePen, x, yMid, x, yMid + MathF.RoundToInt(left * yMid));
                        g.DrawLine(linePen, x, yMid, x, yMid - MathF.RoundToInt(right * yMid));
                    }
                }
            }

            query.Result = result;
        }
Exemplo n.º 2
0
        private void PerformStreamingUpdate(AudioData audioDataRes)
        {
            int num;

            AL.GetSource(this.alSource, ALGetSourcei.BuffersProcessed, out num);
            while (num > 0)
            {
                num--;

                int unqueued;
                unqueued = AL.SourceUnqueueBuffer(this.alSource);

                if (OggVorbis.IsStreamValid(this.strOvStr))
                {
                    PcmData pcm;
                    bool    eof = !OggVorbis.StreamChunk(this.strOvStr, out pcm);
                    if (eof)
                    {
                        OggVorbis.EndStream(ref this.strOvStr);
                        if (this.looped)
                        {
                            OggVorbis.BeginStreamFromMemory(audioDataRes.OggVorbisData, out this.strOvStr);
                            if (pcm.dataLength == 0)
                            {
                                eof = !OggVorbis.StreamChunk(this.strOvStr, out pcm);
                            }
                            else
                            {
                                eof = false;
                            }
                        }
                    }
                    if (pcm.dataLength > 0)
                    {
                        AL.BufferData(
                            unqueued,
                            pcm.channelCount == 1 ? ALFormat.Mono16 : ALFormat.Stereo16,
                            pcm.data,
                            pcm.dataLength * PcmData.SizeOfDataElement,
                            pcm.sampleRate);
                        AL.SourceQueueBuffer(this.alSource, unqueued);
                    }
                    if (pcm.dataLength == 0 || eof)
                    {
                        this.strStopReq = StopRequest.EndOfStream;
                        break;
                    }
                }
            }
        }
Exemplo n.º 3
0
        private void OnDisposed(bool manually)
        {
            if (manually)
            {
                if (this.isStreamed)
                {
                    lock (this.strLock)
                    {
                        OggVorbis.EndStream(ref this.strOvStr);
                    }
                    this.strStopReq = StopRequest.Immediately;
                }

                this.attachedTo  = null;
                this.curPriority = -1;

                lock (this.strLock)
                {
                    if (this.alSource > AlSource_NotAvailable)
                    {
                        this.CleanupAlSource();
                        DualityApp.Sound.FreeAlSource(this.alSource);
                        this.alSource = AlSource_NotAvailable;
                    }
                    if (this.strAlBuffers != null)
                    {
                        for (int i = 0; i < this.strAlBuffers.Length; i++)
                        {
                            if (!AL.IsBuffer(this.strAlBuffers[i]))
                            {
                                return;
                            }
                            AL.DeleteBuffer(this.strAlBuffers[i]);
                        }
                        this.strAlBuffers = null;
                    }
                    this.UnregisterPlaying();
                }
            }
        }
Exemplo n.º 4
0
        private void OnDisposed(bool manually)
        {
            if (manually)
            {
                if (this.strWorker != null && this.strWorker.IsAlive)
                {
                    lock (this.strLock)
                    {
                        OggVorbis.EndStream(ref this.strOvStr);
                    }
                }
                this.strWorker = null;

                this.attachedTo  = null;
                this.curPriority = -1;

                lock (this.strLock)
                {
                    if (this.alSource > AlSource_NotAvailable)
                    {
                        this.CleanupAlSource();
                        DualityApp.Sound.FreeAlSource(this.alSource);
                        this.alSource = AlSource_NotAvailable;
                    }
                    if (this.strAlBuffers != null)
                    {
                        for (int i = 0; i < this.strAlBuffers.Length; i++)
                        {
                            if (!AL.IsBuffer(this.strAlBuffers[i]))
                            {
                                continue;
                            }
                            AL.DeleteBuffer(this.strAlBuffers[i]);
                        }
                        this.strAlBuffers = null;
                    }
                    this.UnregisterPlaying();
                }
            }
        }
Exemplo n.º 5
0
        private void PerformStreamingBegin(AudioData audioDataRes)
        {
            // Generate streaming buffers
            this.strAlBuffers = new int[3];
            for (int i = 0; i < this.strAlBuffers.Length; ++i)
            {
                AL.GenBuffers(1, out this.strAlBuffers[i]);
            }

            // Begin streaming
            OggVorbis.BeginStreamFromMemory(audioDataRes.OggVorbisData, out this.strOvStr);

            // Initially, completely fill all buffers
            for (int i = 0; i < this.strAlBuffers.Length; ++i)
            {
                PcmData pcm;
                bool    eof = !OggVorbis.StreamChunk(this.strOvStr, out pcm);
                if (pcm.dataLength > 0)
                {
                    AL.BufferData(
                        this.strAlBuffers[i],
                        pcm.channelCount == 1 ? ALFormat.Mono16 : ALFormat.Stereo16,
                        pcm.data,
                        pcm.dataLength * PcmData.SizeOfDataElement,
                        pcm.sampleRate);
                    AL.SourceQueueBuffer(this.alSource, this.strAlBuffers[i]);
                    if (eof)
                    {
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
        }
Exemplo n.º 6
0
        public unsafe int DecodeOGG(SoundSample sample, int sampleOffset44k, int sampleCount44k, float *dest)
        {
            int readSamples, totalSamples;

            var shift        = 22050 / sample.objectInfo.nSamplesPerSec;
            var sampleOffset = sampleOffset44k >> shift;
            var sampleCount  = sampleCount44k >> shift;

            // open OGG file if not yet opened
            if (lastSample == null)
            {
                // make sure there is enough space for another decoder
                if (ISampleDecoder.decoderMemoryAllocator.FreeBlockMemory < ISampleDecoder.MIN_OGGVORBIS_MEMORY)
                {
                    return(0);
                }

                if (sample.nonCacheData == null)
                {
                    Debug.Assert(false); failed = true; return(0);
                }                                                                                  // this should never happen
                file.SetData(sample.nonCacheData, sample.objectMemSize);
                if (OggVorbis.ov_openFile(file, ogg) < 0)
                {
                    failed = true; return(0);
                }
                lastFormat = WAVE_FORMAT_TAG.OGG;
                lastSample = sample;
            }

            // seek to the right offset if necessary
            if (sampleOffset != lastSampleOffset && ov_pcm_seek(ogg, sampleOffset / sample.objectInfo.nChannels) != 0)
            {
                failed = true; return(0);
            }

            lastSampleOffset = sampleOffset;

            // decode OGG samples
            totalSamples = sampleCount;
            readSamples  = 0;
            do
            {
                float **samples;
                var     ret = (int)ov_read_float(ogg, &samples, totalSamples / sample.objectInfo.nChannels, null);
                if (ret == 0)
                {
                    failed = true; break;
                }
                if (ret < 0)
                {
                    failed = true; return(0);
                }
                ret *= sample.objectInfo.nChannels;

                Simd.UpSampleOGGTo44kHz(dest + (readSamples << shift), samples, ret, sample.objectInfo.nSamplesPerSec, sample.objectInfo.nChannels);

                readSamples  += ret;
                totalSamples -= ret;
            } while (totalSamples > 0);

            lastSampleOffset += readSamples;

            return(readSamples << shift);
        }
Exemplo n.º 7
0
        private static void ThreadStreamFunc(object param)
        {
            SoundInstance sndInst = (SoundInstance)param;

            while (true)
            {
                lock (sndInst.strLock)
                {
                    if (sndInst.Disposed)
                    {
                        return;
                    }
                    if (!DualityApp.Sound.IsAvailable)
                    {
                        return;
                    }

                    ALSourceState stateTemp = ALSourceState.Stopped;
                    if (sndInst.alSource > AlSource_NotAvailable)
                    {
                        stateTemp = AL.GetSourceState(sndInst.alSource);
                    }

                    if (stateTemp == ALSourceState.Stopped && sndInst.strStopReq != StopRequest.None)
                    {
                        // Stopped due to regular EOF. If strStopReq is NOT set,
                        // the source stopped playing because it reached the end of the buffer
                        // but in fact only because we were too slow inserting new data.
                        return;
                    }
                    else if (sndInst.strStopReq == StopRequest.Immediately)
                    {
                        // Stopped intentionally due to Stop()
                        if (sndInst.alSource > AlSource_NotAvailable)
                        {
                            AL.SourceStop(sndInst.alSource);
                        }
                        return;
                    }

                    Sound     soundRes     = sndInst.sound.Res;
                    AudioData audioDataRes = sndInst.audioData.Res;
                    if (soundRes == null || audioDataRes == null)
                    {
                        sndInst.Dispose();
                        return;
                    }
                    if (stateTemp == ALSourceState.Initial)
                    {
                        // Generate streaming buffers
                        sndInst.strAlBuffers = new int[3];
                        for (int i = 0; i < sndInst.strAlBuffers.Length; ++i)
                        {
                            AL.GenBuffers(1, out sndInst.strAlBuffers[i]);
                        }

                        // Begin streaming
                        OggVorbis.BeginStreamFromMemory(audioDataRes.OggVorbisData, out sndInst.strOvStr);

                        // Initially, completely fill all buffers
                        for (int i = 0; i < sndInst.strAlBuffers.Length; ++i)
                        {
                            PcmData pcm;
                            bool    eof = !OggVorbis.StreamChunk(sndInst.strOvStr, out pcm);
                            if (pcm.dataLength > 0)
                            {
                                AL.BufferData(
                                    sndInst.strAlBuffers[i],
                                    pcm.channelCount == 1 ? ALFormat.Mono16 : ALFormat.Stereo16,
                                    pcm.data,
                                    pcm.dataLength * PcmData.SizeOfDataElement,
                                    pcm.sampleRate);
                                AL.SourceQueueBuffer(sndInst.alSource, sndInst.strAlBuffers[i]);
                                if (eof)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }

                        // Initially play source
                        AL.SourcePlay(sndInst.alSource);
                        stateTemp = AL.GetSourceState(sndInst.alSource);
                    }
                    else
                    {
                        int num;
                        AL.GetSource(sndInst.alSource, ALGetSourcei.BuffersProcessed, out num);
                        while (num > 0)
                        {
                            num--;

                            int unqueued;
                            unqueued = AL.SourceUnqueueBuffer(sndInst.alSource);

                            if (OggVorbis.IsStreamValid(sndInst.strOvStr))
                            {
                                PcmData pcm;
                                bool    eof = !OggVorbis.StreamChunk(sndInst.strOvStr, out pcm);
                                if (eof)
                                {
                                    OggVorbis.EndStream(ref sndInst.strOvStr);
                                    if (sndInst.looped)
                                    {
                                        OggVorbis.BeginStreamFromMemory(audioDataRes.OggVorbisData, out sndInst.strOvStr);
                                        if (pcm.dataLength == 0)
                                        {
                                            eof = !OggVorbis.StreamChunk(sndInst.strOvStr, out pcm);
                                        }
                                    }
                                }
                                if (pcm.dataLength > 0)
                                {
                                    AL.BufferData(
                                        unqueued,
                                        pcm.channelCount == 1 ? ALFormat.Mono16 : ALFormat.Stereo16,
                                        pcm.data,
                                        pcm.dataLength * PcmData.SizeOfDataElement,
                                        pcm.sampleRate);
                                    AL.SourceQueueBuffer(sndInst.alSource, unqueued);
                                }
                                if (pcm.dataLength == 0 || eof)
                                {
                                    sndInst.strStopReq = StopRequest.EndOfStream;
                                    break;
                                }
                            }
                        }
                    }

                    if (stateTemp == ALSourceState.Stopped && sndInst.strStopReq == StopRequest.None)
                    {
                        // If the source stopped unintentionally, restart it. (See above)
                        AL.SourcePlay(sndInst.alSource);
                    }
                }
                Thread.Sleep(16);
            }
        }