/* get information for a sample object.  returns False if not found. */
        public static bool WaveSampDictGetSampleInfo(
            WaveSampDictRec Dict,
            string Name,
            out float[] DataOut,
            out int NumFramesOut,
            out NumChannelsType NumChannelsOut,
            out int Loop1StartOut,
            out int Loop1EndOut,
            out int Loop2StartOut,
            out int Loop2EndOut,
            out int Loop3StartOut,
            out int Loop3EndOut,
            out int OriginOut,
            out double NaturalFreqOut,
            out int SamplingRateOut,
            out bool Loop1Bidirectional,
            out bool Loop2Bidirectional,
            out bool Loop3Bidirectional)
        {
            DataOut            = null;
            NumFramesOut       = 0;
            NumChannelsOut     = 0;
            Loop1StartOut      = 0;
            Loop1EndOut        = 0;
            Loop2StartOut      = 0;
            Loop2EndOut        = 0;
            Loop3StartOut      = 0;
            Loop3EndOut        = 0;
            OriginOut          = 0;
            NaturalFreqOut     = 0;
            SamplingRateOut    = 0;
            Loop1Bidirectional = false;
            Loop2Bidirectional = false;
            Loop3Bidirectional = false;

            SampleRec Sample;

            if (!Dict.Samples.TryGetValue(Name, out Sample))
            {
                return(false);
            }

            DataOut            = Sample.SampleDataReference;
            NumFramesOut       = Sample.NumFrames;
            NumChannelsOut     = Sample.NumChannels;
            Loop1StartOut      = Sample.Loop1Start;
            Loop1EndOut        = Sample.Loop1End;
            Loop2StartOut      = Sample.Loop2Start;
            Loop2EndOut        = Sample.Loop2End;
            Loop3StartOut      = Sample.Loop3Start;
            Loop3EndOut        = Sample.Loop3End;
            OriginOut          = Sample.Origin;
            NaturalFreqOut     = Sample.NaturalFreq;
            SamplingRateOut    = Sample.SamplingRate;
            Loop1Bidirectional = Sample.Loop1Bidirectional;
            Loop2Bidirectional = Sample.Loop2Bidirectional;
            Loop3Bidirectional = Sample.Loop3Bidirectional;

            return(true);
        }
Example #2
0
        public static OutputGeneric<T, WaveTableTestGeneratorParams<T, W>, W> Do(
            string baseName,
            GetDestinationMethod<T> getDestination,
            CreateDestinationHandlerMethod<T, W> createDestinationHandler,
            W destinationHandlerArguments,
            GeneratorMainLoopMethod<T, WaveTableTestGeneratorParams<T, W>, W> generatorMainLoop,
            WaveTableTestGeneratorParams<T, W> generatorParams,
            GeneratorCompletionMethod<WaveTableTestGeneratorParams<T, W>> generatorCompletion,
            IMainWindowServices mainWindow,
            NumChannelsType channels,
            NumBitsType bits,
            int samplingRate,
            int oversamplingFactor,
            bool showProgressWindow,
            bool modal)
        {
            // prerequisites 

            return OutputGeneric<T, WaveTableTestGeneratorParams<T, W>, W>.Do(
                baseName,
                getDestination,
                createDestinationHandler,
                destinationHandlerArguments,
                generatorMainLoop,
                generatorParams,
                generatorCompletion,
                channels,
                bits,
                samplingRate,
                oversamplingFactor,
                showProgressWindow,
                modal);
        }
Example #3
0
        public AIFFWriter(
            Stream outputStream,
            NumChannelsType channels,
            NumBitsType bits,
            int samplingRate)
        {
            this.outputStream = outputStream;
            this.start        = outputStream.Position;

            this.channels     = channels;
            this.bits         = bits;
            this.samplingRate = samplingRate;

            switch (bits)
            {
            default:
                Debug.Assert(false);
                throw new InvalidOperationException();

            case NumBitsType.eSample8bit:
                expander      = Expander_8;
                bytesPerPoint = 1;
                break;

            case NumBitsType.eSample16bit:
                expander      = Expander_16;
                bytesPerPoint = 2;
                break;

            case NumBitsType.eSample24bit:
                expander      = Expander_24;
                bytesPerPoint = 3;
                break;
            }

            switch (channels)
            {
            default:
                Debug.Assert(false);
                throw new InvalidOperationException();

            case NumChannelsType.eSampleMono:
                pointsPerFrame = 1;
                break;

            case NumChannelsType.eSampleStereo:
                pointsPerFrame = 2;
                break;
            }

            SetUpAIFFHeader(
                outputStream,
                channels,
                bits,
                samplingRate);
        }
Example #4
0
 public static DestinationHandler <OutputSelectableFileDestination> CreateOutputSelectableFileDestinationHandler(
     OutputSelectableFileDestination destination,
     NumChannelsType channels,
     NumBitsType bits,
     int samplingRate,
     OutputSelectableFileArguments arguments)
 {
     return(new OutputSelectableFileDestinationHandler(
                destination.path,
                channels,
                bits,
                samplingRate,
                arguments));
 }
        public static OutputGeneric <T, SynthesizerGeneratorParams <T, W>, W> Do(
            string baseName,
            GetDestinationMethod <T> getDestination,
            CreateDestinationHandlerMethod <T, W> createDestinationHandler,
            W destinationHandlerArguments,
            GeneratorMainLoopMethod <T, SynthesizerGeneratorParams <T, W>, W> generatorMainLoop,
            SynthesizerGeneratorParams <T, W> generatorParams,
            GeneratorCompletionMethod <SynthesizerGeneratorParams <T, W> > generatorCompletion,
            IMainWindowServices mainWindow,
            NumChannelsType channels,
            NumBitsType bits,
            int samplingRate,
            int oversamplingFactor,
            bool showProgressWindow,
            bool modal)
        {
            // prerequisites

            /* force an auto-save since play may take a long time */
            MainWindow.DoAutosaveGlobally();

            /* make sure all objects are up to date */
            if (!mainWindow.MakeUpToDate())
            {
                /* couldn't compile score elements */
                return(null);
            }

            return(OutputGeneric <T, SynthesizerGeneratorParams <T, W>, W> .Do(
                       baseName,
                       getDestination,
                       createDestinationHandler,
                       destinationHandlerArguments,
                       generatorMainLoop,
                       generatorParams,
                       generatorCompletion,
                       channels,
                       bits,
                       samplingRate,
                       oversamplingFactor,
                       showProgressWindow,
                       modal));
        }
 public SynthesizerGeneratorParams(
     IMainWindowServices mainWindow,
     Document document,
     List <TrackObjectRec> listOfTracks,
     TrackObjectRec keyTrack,
     int frameToStartAt,
     int samplingRate,
     int envelopeRate,
     NumChannelsType channels,
     LargeBCDType defaultBeatsPerMinute,
     double overallVolumeScalingReciprocal,
     LargeBCDType scanningGap,
     NumBitsType bits,
     bool clipWarn,
     int oversamplingFactor,
     bool showSummary,
     bool deterministic,// now ignored - control by setting randomSeed to null or int
     int?randomSeed,
     Synthesizer.AutomationSettings automationSettings)
 {
     this.mainWindow                     = mainWindow;
     this.document                       = document;
     this.listOfTracks                   = listOfTracks;
     this.keyTrack                       = keyTrack;
     this.frameToStartAt                 = frameToStartAt;
     this.samplingRate                   = samplingRate;
     this.envelopeRate                   = envelopeRate;
     this.channels                       = channels;
     this.defaultBeatsPerMinute          = defaultBeatsPerMinute;
     this.overallVolumeScalingReciprocal = overallVolumeScalingReciprocal;
     this.scanningGap                    = scanningGap;
     this.bits               = bits;
     this.clipWarn           = clipWarn;
     this.oversamplingFactor = oversamplingFactor;
     this.showSummary        = showSummary;
     this.deterministic      = deterministic;
     this.randomSeed         = randomSeed;
     this.automationSettings = automationSettings;
 }
Example #7
0
        public OutputSelectableFileDestinationHandler(
            string destinationPath,
            NumChannelsType channels,
            NumBitsType bits,
            int samplingRate,
            OutputSelectableFileArguments arguments)
        {
            outputStream = new FileStream(
                destinationPath,
                FileMode.Create,
                FileAccess.ReadWrite,
                FileShare.None,
                Constants.BufferSize);
            switch (Path.GetExtension(destinationPath).ToLowerInvariant())
            {
            default:
                Debug.Assert(false);
                throw new ArgumentException();

            case ".wav":
                outputWriter = new WAVWriter(
                    outputStream,
                    channels,
                    bits,
                    samplingRate);
                break;

            case ".aif":
            case ".aiff":
                outputWriter = new AIFFWriter(
                    outputStream,
                    channels,
                    bits,
                    samplingRate);
                break;
            }
        }
Example #8
0
            public Source(Document document)
            {
                _document = document;

                _SamplingRate               = document.SamplingRate;
                _EnvelopeUpdateRate         = document.EnvelopeUpdateRate;
                _Oversampling               = document.Oversampling;
                _DefaultBeatsPerMinute      = (LargeBCDType)document.DefaultBeatsPerMinute;
                _OverallVolumeScalingFactor = (LargeBCDType)document.OverallVolumeScalingFactor;
                _OutputNumBits              = document.OutputNumBits;
                _ScanningGap    = (LargeBCDType)document.ScanningGap;
                _BufferDuration = (LargeBCDType)document.BufferDuration;
                _ClipWarning    = document.ClipWarning;
                _NumChannels    = document.NumChannels;
                _ShowSummary    = document.ShowSummary;
                _Deterministic  = document.Deterministic;
                _Seed           = document.Seed;
                foreach (TrackObjectRec Track in document.TrackList)
                {
                    IncludedTracks.Add(new TrackInclusionRec(Track, this));
                }

                document.TrackList.ListChanged += TrackList_ListChanged;
            }
Example #9
0
        /* RIFF file format, with WAVE information */
        /*  'RIFF' */
        /*  4-byte little endian length descriptor (minus 8 bytes for these 2 fields) */
        /*  'WAVE' */
        /*  'fmt ' */
        /*  4-byte little endian length descriptor for the 'fmt ' header block */
        /*      - this should be 16.  if not, then it's some other kind of WAV file */
        /*  2-byte little endian format descriptor.  this is always here. */
        /*      - 1 = PCM */
        /*    for future use: */
        /*      - 3 = IEEE floats */
        /*    and just in case: */
        /*      - 6 = 8-bit ITU-T G.711 A-law */
        /*      - 7 = 8-bit ITU-T G.711 mu-law */
        /*      - 0xFFFE = extensible (requires SubFormat field) */
        /*  2-byte little endian number of channels. */
        /*  4-byte little endian sampling rate integer. */
        /*  4-byte little endian average bytes per second. */
        /*  2-byte little endian block align.  for 8-bit mono, this is 1; for 16-bit */
        /*    stereo, this is 4. */
        /*  2-byte little endian number of bits. */
        /*      - 8 = 8-bit */
        /*      - 16 = 16-bit */
        /*      - 24 = 24-bit */
        /*  'data' */
        /*  4-byte little endian length of sample data descriptor */
        /*  any length data.  8-bit data goes from 0..255, but 16-bit data goes */
        /*    from -32768 to 32767. */
        private static void SetUpWAVHeader(
            Stream outputStream,
            NumChannelsType channels,
            NumBitsType bits,
            int samplingRate)
        {
            using (BinaryWriter writer = new BinaryWriter(outputStream))
            {
                int   bytesPerSecond;
                short blockAlignment;

                /*  'RIFF' */
                writer.WriteFixedStringASCII(4, "RIFF");

                /* figure out how long chunk will be */
                switch (bits)
                {
                default:
                    Debug.Assert(false);
                    throw new ArgumentException();

                case NumBitsType.eSample8bit:
                    switch (channels)
                    {
                    default:
                        Debug.Assert(false);
                        throw new ArgumentException();

                    case NumChannelsType.eSampleMono:
                        bytesPerSecond = samplingRate * 1;
                        blockAlignment = 1;
                        break;

                    case NumChannelsType.eSampleStereo:
                        bytesPerSecond = samplingRate * 2;
                        blockAlignment = 2;
                        break;
                    }
                    break;

                case NumBitsType.eSample16bit:
                    switch (channels)
                    {
                    default:
                        Debug.Assert(false);
                        throw new ArgumentException();

                    case NumChannelsType.eSampleMono:
                        bytesPerSecond = samplingRate * 2;
                        blockAlignment = 2;
                        break;

                    case NumChannelsType.eSampleStereo:
                        bytesPerSecond = samplingRate * 4;
                        blockAlignment = 4;
                        break;
                    }
                    break;

                case NumBitsType.eSample24bit:
                    switch (channels)
                    {
                    default:
                        Debug.Assert(false);
                        throw new ArgumentException();

                    case NumChannelsType.eSampleMono:
                        bytesPerSecond = samplingRate * 3;
                        blockAlignment = 3;
                        break;

                    case NumChannelsType.eSampleStereo:
                        bytesPerSecond = samplingRate * 6;
                        blockAlignment = 6;
                        break;
                    }
                    break;
                }

                /*  4-byte little endian length descriptor (minus 8 bytes for these 2 fields) */
                writer.WriteInt32(0); // placeholder - corrected later

                /*  'WAVE' */
                writer.WriteFixedStringASCII(4, "WAVE");
                /*  'fmt ' */
                writer.WriteFixedStringASCII(4, "fmt ");

                /*  4-byte little endian length descriptor for the 'fmt ' header block */
                /*      - this should be 16.  if not, then it's some other kind of WAV file */
                writer.WriteInt32(16);

                /*  2-byte little endian format descriptor.  this is always here. */
                /*      - 1 = PCM */
                writer.WriteInt16(1);

                /*  2-byte little endian number of channels. */
                switch (channels)
                {
                default:
                    Debug.Assert(false);
                    throw new ArgumentException();

                case NumChannelsType.eSampleMono:
                    writer.WriteInt16(1);
                    break;

                case NumChannelsType.eSampleStereo:
                    writer.WriteInt16(2);
                    break;
                }

                /*  4-byte little endian sampling rate integer. */
                writer.WriteInt32(samplingRate);

                /*  4-byte little endian average bytes per second. */
                writer.WriteInt32(bytesPerSecond);

                /*  2-byte little endian block align.  for 8-bit mono, this is 1; for 16-bit */
                /*    stereo, this is 4. */
                writer.WriteInt16(blockAlignment);

                /*  2-byte little endian number of bits. */
                /*      - 8 = 8-bit */
                /*      - 16 = 16-bit */
                /*      - 24 = 24-bit */
                switch (bits)
                {
                default:
                    Debug.Assert(false);
                    throw new ArgumentException();

                case NumBitsType.eSample8bit:
                    writer.WriteInt16(8);
                    break;

                case NumBitsType.eSample16bit:
                    writer.WriteInt16(16);
                    break;

                case NumBitsType.eSample24bit:
                    writer.WriteInt16(24);
                    break;
                }

                /*  'data' */
                writer.WriteFixedStringASCII(4, "data");

                /*  4-byte little endian length of sample data descriptor */
                writer.WriteInt32(0); // placeholder - corrected later

                /*  any length data.  8-bit data goes from 0..255, but 16-bit data goes */
                /*    from -32768 to 32767. */
            }
        }
Example #10
0
        /* RIFF file format, with WAVE information */
        /*  'RIFF' */
        /*  4-byte little endian length descriptor (minus 8 bytes for these 2 fields) */
        /*  'WAVE' */
        /*  'fmt ' */
        /*  4-byte little endian length descriptor for the 'fmt ' header block */
        /*      - this should be 16.  if not, then it's some other kind of WAV file */
        /*  2-byte little endian format descriptor.  this is always here. */
        /*      - 1 = PCM */
        /*  2-byte little endian number of channels. */
        /*  4-byte little endian sampling rate integer. */
        /*  4-byte little endian average bytes per second. */
        /*  2-byte little endian block align.  for 8-bit mono, this is 1; for 16-bit */
        /*    stereo, this is 4. */
        /*  2-byte little endian number of bits. */
        /*      - 8 = 8-bit */
        /*      - 16 = 16-bit */
        /*      - 24 = 24-bit */
        /*  'data' */
        /*  4-byte little endian length of sample data descriptor */
        /*  any length data.  8-bit data goes from 0..255, but 16-bit data goes */
        /*    from -32768 to 32767. */
        public static void ReadPreamble(
            Stream stream,
            out NumBitsType numBitsOut,
            out NumChannelsType numChannelsOut,
            out int numSampleFramesOut,
            out int samplingRateOut)
        {
            NumBitsType     numBits;
            NumChannelsType numChannels;
            int             numSampleFrames;
            int             samplingRate;
            long            audioDataOffset;

            numBitsOut         = (NumBitsType)0;
            numChannelsOut     = (NumChannelsType)0;
            numSampleFramesOut = 0;
            samplingRateOut    = 0;

            try
            {
                using (BinaryReader File = new BinaryReader(stream))
                {
                    string stringBuffer;

                    /*  'RIFF' */
                    stringBuffer = File.ReadFixedStringASCII(4);
                    if (!String.Equals(stringBuffer, "RIFF"))
                    {
                        throw new AudioFileReaderException(AudioFileReaderErrors.UnrecognizedFileFormat);
                    }

                    /*  4-byte little endian length descriptor (minus 8 bytes for these 2 fields) */
                    int totalFileLength = File.ReadInt32();

                    /*  'WAVE' */
                    stringBuffer = File.ReadFixedStringASCII(4);
                    if (!String.Equals(stringBuffer, "WAVE"))
                    {
                        throw new AudioFileReaderException(AudioFileReaderErrors.UnrecognizedFileFormat);
                    }

                    /*  'fmt ' */
                    stringBuffer = File.ReadFixedStringASCII(4);
                    if (!String.Equals(stringBuffer, "fmt "))
                    {
                        throw new AudioFileReaderException(AudioFileReaderErrors.UnrecognizedFileFormat);
                    }

                    /*  4-byte little endian length descriptor for the 'fmt ' header block */
                    /*      - this should be 16.  if not, then it's some other kind of WAV file */
                    int headerLength = File.ReadInt32();
                    if (headerLength != 16)
                    {
                        throw new AudioFileReaderException(AudioFileReaderErrors.UnrecognizedFileFormat);
                    }

                    /*  2-byte little endian format descriptor.  this is always here. */
                    /*      - 1 = PCM */
                    short dataTypeDescriptor = File.ReadInt16();
                    if (dataTypeDescriptor != 1)
                    {
                        throw new AudioFileReaderException(AudioFileReaderErrors.NotUncompressedPCM);
                    }

                    /*  2-byte little endian number of channels. */
                    short numberOfChannelsRaw = File.ReadInt16();
                    if ((numberOfChannelsRaw != 1) && (numberOfChannelsRaw != 2))
                    {
                        throw new AudioFileReaderException(AudioFileReaderErrors.UnsupportedNumberOfChannels);
                    }

                    /*  4-byte little endian sampling rate integer. */
                    samplingRate = File.ReadInt32();

                    /*  4-byte little endian average bytes per second. */
                    int averageBytesPerSecond = File.ReadInt32();

                    /*  2-byte little endian block align.  for 8-bit mono, this is 1; for 16-bit */
                    /*    stereo, this is 4. */
                    short blockAlignment = File.ReadInt16();

                    /*  2-byte little endian number of bits. */
                    /*      - 8 = 8-bit */
                    /*      - 16 = 16-bit */
                    /*      - 24 = 24-bit */
                    short numberOfBitsRaw = File.ReadInt16();
                    switch (numberOfBitsRaw)
                    {
                    default:
                        throw new AudioFileReaderException(AudioFileReaderErrors.UnsupportedNumberOfBits);

                    case 8:
                        numBits = NumBitsType.eSample8bit;
                        break;

                    case 16:
                        numBits = NumBitsType.eSample16bit;
                        break;

                    case 24:
                        numBits = NumBitsType.eSample24bit;
                        break;
                    }

                    /*  'data' */
                    stringBuffer = File.ReadFixedStringASCII(4);
                    if (!String.Equals(stringBuffer, "data"))
                    {
                        throw new AudioFileReaderException(AudioFileReaderErrors.UnrecognizedFileFormat);
                    }

                    /*  4-byte little endian length of sample data descriptor */
                    int sampledNumberOfBytes = File.ReadInt32();

                    audioDataOffset = stream.Position;

                    /* calculate number of sample frames */
                    switch (numBits)
                    {
                    default:
                        Debug.Assert(false);
                        throw new InvalidOperationException();

                    case NumBitsType.eSample8bit:
                        switch (numberOfChannelsRaw)
                        {
                        default:
                            Debug.Assert(false);
                            throw new InvalidOperationException();

                        case 1:
                            numSampleFrames = sampledNumberOfBytes / 1;
                            break;

                        case 2:
                            numSampleFrames = sampledNumberOfBytes / 2;
                            break;
                        }
                        break;

                    case NumBitsType.eSample16bit:
                        switch (numberOfChannelsRaw)
                        {
                        default:
                            Debug.Assert(false);
                            throw new InvalidOperationException();

                        case 1:
                            numSampleFrames = sampledNumberOfBytes / 2;
                            break;

                        case 2:
                            numSampleFrames = sampledNumberOfBytes / 4;
                            break;
                        }
                        break;

                    case NumBitsType.eSample24bit:
                        switch (numberOfChannelsRaw)
                        {
                        default:
                            Debug.Assert(false);
                            throw new InvalidOperationException();

                        case 1:
                            numSampleFrames = sampledNumberOfBytes / 3;
                            break;

                        case 2:
                            numSampleFrames = sampledNumberOfBytes / 6;
                            break;
                        }
                        break;
                    }

                    /*  any length data.  8-bit data goes from 0..255, but 16-bit data goes */
                    /*    from -32768 to 32767. */
                    switch (numberOfChannelsRaw)
                    {
                    default:
                        Debug.Assert(false);
                        throw new InvalidOperationException();

                    case 1:
                        numChannels = NumChannelsType.eSampleMono;
                        break;

                    case 2:
                        numChannels = NumChannelsType.eSampleStereo;
                        break;
                    }
                }
            }
            catch (InvalidDataException)
            {
                throw new AudioFileReaderException(AudioFileReaderErrors.InvalidData);
            }

            numBitsOut         = numBits;
            numChannelsOut     = numChannels;
            numSampleFramesOut = numSampleFrames;
            samplingRateOut    = samplingRate;

            stream.Seek(audioDataOffset, SeekOrigin.Begin);
        }
Example #11
0
        /* obtain a data reference & info for a sample.  returns False if there is no */
        /* sample corresponding to the supplied frequency. */
        public static bool GetMultiSampleReference(
            MultiSampleRec MultiSample,
            double FrequencyHertz,
            out float[] DataOut,
            out int NumFramesOut,
            out NumChannelsType NumChannelsOut,
            out int Loop1StartOut,
            out int Loop1EndOut,
            out int Loop2StartOut,
            out int Loop2EndOut,
            out int Loop3StartOut,
            out int Loop3EndOut,
            out int OriginOut,
            out double NaturalFreqOut,
            out int SamplingRateOut,
            out bool Loop1Bidirectional,
            out bool Loop2Bidirectional,
            out bool Loop3Bidirectional)
        {
            for (int i = 0; i < MultiSample.SampleInfoArray.Length; i += 1)
            {
                OneSampleRec Entry = MultiSample.SampleInfoArray[i];

                if ((FrequencyHertz >= Entry.MinFrequency) && (FrequencyHertz < Entry.MaxFrequency))
                {
                    DataOut            = Entry.SampleDataReference;
                    NumFramesOut       = Entry.NumFrames;
                    NumChannelsOut     = Entry.NumChannels;
                    Loop1StartOut      = Entry.Loop1Start;
                    Loop1EndOut        = Entry.Loop1End;
                    Loop2StartOut      = Entry.Loop2Start;
                    Loop2EndOut        = Entry.Loop2End;
                    Loop3StartOut      = Entry.Loop3Start;
                    Loop3EndOut        = Entry.Loop3End;
                    Loop1Bidirectional = Entry.Loop1Bidirectional;
                    Loop2Bidirectional = Entry.Loop2Bidirectional;
                    Loop3Bidirectional = Entry.Loop3Bidirectional;
                    OriginOut          = Entry.Origin;
                    NaturalFreqOut     = Entry.NaturalFreq;
                    SamplingRateOut    = Entry.SamplingRate;
                    return(true);
                }
            }

            DataOut            = null;
            NumFramesOut       = 0;
            NumChannelsOut     = (NumChannelsType)0;
            Loop1StartOut      = 0;
            Loop1EndOut        = 0;
            Loop2StartOut      = 0;
            Loop2EndOut        = 0;
            Loop3StartOut      = 0;
            Loop3EndOut        = 0;
            Loop1Bidirectional = false;
            Loop2Bidirectional = false;
            Loop3Bidirectional = false;
            OriginOut          = 0;
            NaturalFreqOut     = 0;
            SamplingRateOut    = 0;
            return(false);
        }
Example #12
0
        /* AIFF/AIFF-C File Format: */
        /*     "FORM" */
        /*     4-byte big endian form chunk length descriptor (minus 8 for "FORM" & this) */
        /*     4-byte type */
        /*        "AIFF" = AIFF format file */
        /*        "AIFC" = AIFF-C format file */
        /* in any order, these chunks can occur: */
        /*   Version Chunk (this only occurs in AIFF-C files) */
        /*     "FVER" */
        /*     4-byte big endian length, which should always be the value 4 (four) */
        /*     4-byte date code.  this is probably 0xA2805140 (stored big endian), but it */
        /*          probably doesn't matter. */
        /*   Common Chunk for AIFF files */
        /*     "COMM" */
        /*     4-byte big endian length. */
        /*        always 18 for AIFF files */
        /*     2-byte big endian number of channels */
        /*     4-byte big endian number of sample frames */
        /*     2-byte big endian number of bits per sample */
        /*        a value in the domain 1..32 */
        /*     10-byte extended precision number of frames per second */
        /*   Common Chunk for AIFF-C files */
        /*     "COMM" */
        /*     4-byte big endian length. */
        /*        22 + compression method string length for AIFF-C files */
        /*     2-byte big endian number of channels */
        /*     4-byte big endian number of sample frames */
        /*     2-byte big endian number of bits per sample */
        /*        a value in the domain 1..32 */
        /*     10-byte extended precision number of frames per second */
        /*     4-byte character code ID for the compression method */
        /*        "NONE" means there is no compression method used */
        /*     some characters in a string identifying the compression method */
        /*        this must be padded to an even number of bytes, but the pad is */
        /*        NOT included in the length descriptor for the chunk. */
        /*        for uncompressed data, the string should be */
        /*        "\x0enot compressed\x00", including the null, for 16 bytes. */
        /*        the total chunk length is thus 38 bytes. */
        /*   Sound Data Chunk */
        /*     "SSND" */
        /*     4-byte big endian number of bytes in sample data array */
        /*     4-byte big endian offset to the first byte of sample data in the array */
        /*     4-byte big endian number of bytes to which the sound data is aligned. */
        /*     any length vector of raw sound data. */
        /*        this must be padded to an even number of bytes, but the pad is */
        /*        NOT included in the length descriptor for the chunk. */
        /*        Samples are stored in an integral number of bytes, the smallest that */
        /*        is required for the specified number of bits.  If this is not an even */
        /*        multiple of 8, then the data is shifted left and the low bits are zeroed */
        /*        Multichannel sound is interleaved with the left channel first. */
        private static void ReadPreamble(
            Stream stream,
            out NumBitsType numBitsOut,
            out NumChannelsType numChannelsOut,
            out int numSampleFramesOut,
            out int samplingRateOut)
        {
            NumBitsType     numBits                = (NumBitsType)(-1);
            bool            numBitsIsValid         = false;
            NumChannelsType numChannels            = (NumChannelsType)(-1);
            bool            numChannelsIsValid     = false;
            int             numSampleFrames        = -1;
            bool            numSampleFramesIsValid = false;
            int             samplingRate           = -1;
            bool            samplingRateIsValid    = false;
            long            audioDataOffset        = 0;
            bool            rawDataFromFileIsValid = false;

            numBitsOut         = (NumBitsType)0;
            numChannelsOut     = (NumChannelsType)0;
            numSampleFramesOut = 0;
            samplingRateOut    = 0;

            try
            {
                using (BinaryReader File = new BinaryReader(stream))
                {
                    string charBuff;

                    /*     "FORM" */
                    charBuff = File.ReadFixedStringASCII(4);
                    if (!String.Equals(charBuff, "FORM"))
                    {
                        throw new AudioFileReaderException(AudioFileReaderErrors.UnrecognizedFileFormat);
                    }

                    /*     4-byte big endian form chunk length descriptor (minus 8 for "FORM" & this) */
                    int formChunkLength = File.ReadInt32BigEndian();

                    /*     4-byte type */
                    /*        "AIFF" = AIFF format file */
                    /*        "AIFC" = AIFF-C format file */
                    charBuff = File.ReadFixedStringASCII(4);
                    bool isAIFFC;
                    if (String.Equals(charBuff, "AIFF"))
                    {
                        isAIFFC = false;
                    }
                    else if (String.Equals(charBuff, "AIFC"))
                    {
                        isAIFFC = true;
                    }
                    else
                    {
                        throw new AudioFileReaderException(AudioFileReaderErrors.UnsupportedVariant);
                    }
                    formChunkLength -= 4;

                    /* now, read in chunks until we die */
                    while (formChunkLength > 0)
                    {
                        /* get the chunk type */
                        charBuff = File.ReadFixedStringASCII(4);
                        /* get the chunk length */
                        int localChunkLength = File.ReadInt32BigEndian();
                        formChunkLength -= 8;
                        /* adjust for even alignment */
                        if ((localChunkLength % 2) != 0)
                        {
                            localChunkLength += 1;
                        }
                        formChunkLength -= localChunkLength;

                        /* decode the chunk */
                        if (String.Equals(charBuff, "COMM"))
                        {
                            uint   exponent;
                            uint   mantissa;
                            byte[] extended = new byte[10];

                            if (!isAIFFC)
                            {
                                short s;

                                /*   Common Chunk for AIFF files */
                                /*     "COMM" */
                                /*     4-byte big endian length. */
                                /*        always 18 for AIFF files */
                                if (localChunkLength != 18)
                                {
                                    throw new AudioFileReaderException(AudioFileReaderErrors.UnsupportedVariant);
                                }

                                /*     2-byte big endian number of channels */
                                s = File.ReadInt16BigEndian();
                                switch (s)
                                {
                                default:
                                    throw new AudioFileReaderException(AudioFileReaderErrors.UnsupportedNumberOfChannels);

                                case 1:
                                    numChannels        = NumChannelsType.eSampleMono;
                                    numChannelsIsValid = true;
                                    break;

                                case 2:
                                    numChannels        = NumChannelsType.eSampleStereo;
                                    numChannelsIsValid = true;
                                    break;
                                }

                                /*     4-byte big endian number of sample frames */
                                numSampleFrames        = File.ReadInt32BigEndian();
                                numSampleFramesIsValid = true;

                                /*     2-byte big endian number of bits per sample */
                                /*        a value in the domain 1..32 */
                                s = File.ReadInt16BigEndian();
                                switch (s)
                                {
                                default:
                                    throw new AudioFileReaderException(AudioFileReaderErrors.UnsupportedNumberOfBits);

                                case 1:
                                case 2:
                                case 3:
                                case 4:
                                case 5:
                                case 6:
                                case 7:
                                case 8:
                                    numBits        = NumBitsType.eSample8bit;
                                    numBitsIsValid = true;
                                    break;

                                case 9:
                                case 10:
                                case 11:
                                case 12:
                                case 13:
                                case 14:
                                case 15:
                                case 16:
                                    numBits        = NumBitsType.eSample16bit;
                                    numBitsIsValid = true;
                                    break;

                                case 17:
                                case 18:
                                case 19:
                                case 20:
                                case 21:
                                case 22:
                                case 23:
                                case 24:
                                    numBits        = NumBitsType.eSample24bit;
                                    numBitsIsValid = true;
                                    break;
                                }

                                /*     10-byte extended precision number of frames per second */
                                File.ReadRaw(extended, 0, 10);
                            }
                            else
                            {
                                short s;

                                /*   Common Chunk for AIFF-C files */
                                /*     "COMM" */
                                /*     4-byte big endian length. */
                                /*        always 18 for AIFF files */
                                if (localChunkLength < 22)
                                {
                                    throw new AudioFileReaderException(AudioFileReaderErrors.UnsupportedVariant);
                                }

                                /*     2-byte big endian number of channels */
                                s = File.ReadInt16BigEndian();
                                switch (s)
                                {
                                default:
                                    throw new AudioFileReaderException(AudioFileReaderErrors.UnsupportedNumberOfChannels);

                                case 1:
                                    numChannels        = NumChannelsType.eSampleMono;
                                    numChannelsIsValid = true;
                                    break;

                                case 2:
                                    numChannels        = NumChannelsType.eSampleStereo;
                                    numChannelsIsValid = true;
                                    break;
                                }

                                /*     4-byte big endian number of sample frames */
                                numSampleFrames        = File.ReadInt32BigEndian();
                                numSampleFramesIsValid = true;

                                /*     2-byte big endian number of bits per sample */
                                /*        a value in the domain 1..32 */
                                s = File.ReadInt16BigEndian();
                                switch (s)
                                {
                                default:
                                    throw new AudioFileReaderException(AudioFileReaderErrors.UnsupportedNumberOfBits);

                                case 1:
                                case 2:
                                case 3:
                                case 4:
                                case 5:
                                case 6:
                                case 7:
                                case 8:
                                    numBits        = NumBitsType.eSample8bit;
                                    numBitsIsValid = true;
                                    break;

                                case 9:
                                case 10:
                                case 11:
                                case 12:
                                case 13:
                                case 14:
                                case 15:
                                case 16:
                                    numBits        = NumBitsType.eSample16bit;
                                    numBitsIsValid = true;
                                    break;

                                case 17:
                                case 18:
                                case 19:
                                case 20:
                                case 21:
                                case 22:
                                case 23:
                                case 24:
                                    numBits        = NumBitsType.eSample24bit;
                                    numBitsIsValid = true;
                                    break;
                                }

                                /*     10-byte extended precision number of frames per second */
                                File.ReadRaw(extended, 0, 10);

                                /*     4-byte character code ID for the compression method */
                                /*        "NONE" means there is no compression method used */
                                charBuff = File.ReadFixedStringASCII(4);
                                if (!String.Equals(charBuff, "NONE"))
                                {
                                    throw new AudioFileReaderException(AudioFileReaderErrors.NotUncompressedPCM);
                                }

                                /*     some characters in a string identifying the compression method */
                                /*        this must be padded to an even number of bytes, but the pad is */
                                /*        NOT included in the length descriptor for the chunk. */
                                /*        for uncompressed data, the string should be */
                                /*        "\x0enot compressed\x00", including the null, for 16 bytes. */
                                /*        the total chunk length is thus 38 bytes. */
                                for (int i = 0; i < localChunkLength - 22; i++)
                                {
                                    File.ReadByte();
                                }
                            }

                            /* extended 22050 = 400D AC44000000000000 */
                            /* extended 22051 = 400D AC46000000000000 */
                            /* extended 44100 = 400E AC44000000000000 */
                            /* extended 44101 = 400E AC45000000000000 */
                            exponent = (((uint)extended[0] & 0xff) << 8)
                                       | ((uint)extended[1] & 0xff);
                            mantissa = (((uint)extended[2] & 0xff) << 24)
                                       | (((uint)extended[3] & 0xff) << 16)
                                       | (((uint)extended[4] & 0xff) << 8)
                                       | ((uint)extended[5] & 0xff);
                            samplingRate = (int)(mantissa >> (0x401e - (int)exponent));
                            if (samplingRate < Constants.MINSAMPLINGRATE)
                            {
                                samplingRate = Constants.MINSAMPLINGRATE;
                            }
                            if (samplingRate > Constants.MAXSAMPLINGRATE)
                            {
                                samplingRate = Constants.MAXSAMPLINGRATE;
                            }
                            samplingRateIsValid = true;
                        }
                        else if (String.Equals(charBuff, "SSND"))
                        {
                            /*   Sound Data Chunk */
                            /*     "SSND" */
                            /*     4-byte big endian number of bytes in sample data array */

                            /* only one of these is allowed */
                            if (rawDataFromFileIsValid)
                            {
                                throw new AudioFileReaderException(AudioFileReaderErrors.UnsupportedVariant);
                            }

                            /*     4-byte big endian offset to the first byte of sample data in the array */
                            int offsetToFirstByte = File.ReadInt32BigEndian();
                            if (offsetToFirstByte != 0)
                            {
                                throw new AudioFileReaderException(AudioFileReaderErrors.UnsupportedVariant);
                            }

                            /*     4-byte big endian number of bytes to which the sound data is aligned. */
                            int alignmentFactor = File.ReadInt32BigEndian();
                            if (alignmentFactor != 0)
                            {
                                throw new AudioFileReaderException(AudioFileReaderErrors.UnsupportedVariant);
                            }

                            /*     any length vector of raw sound data. */
                            /*        this must be padded to an even number of bytes, but the pad is */
                            /*        NOT included in the length descriptor for the chunk. */
                            /*        Samples are stored in an integral number of bytes, the smallest that */
                            /*        is required for the specified number of bits.  If this is not an even */
                            /*        multiple of 8, then the data is shifted left and the low bits are zeroed */
                            /*        Multichannel sound is interleaved with the left channel first. */
                            if (stream.Length - stream.Position < localChunkLength - 8)
                            {
                                throw new AudioFileReaderException(AudioFileReaderErrors.Truncated);
                            }
                            rawDataFromFileIsValid = true;
                            audioDataOffset        = stream.Position;

                            stream.Seek(localChunkLength - 8, SeekOrigin.Current);
                        }
                        else
                        {
                            /* just read the data & get rid of it */
                            while (localChunkLength > 0)
                            {
                                File.ReadByte();
                                localChunkLength -= 1;
                            }
                        }
                    }
                }
            }
            catch (InvalidDataException)
            {
                throw new AudioFileReaderException(AudioFileReaderErrors.InvalidData);
            }

            if (!rawDataFromFileIsValid || !numBitsIsValid || !numChannelsIsValid || !samplingRateIsValid || !numSampleFramesIsValid)
            {
                throw new AudioFileReaderException(AudioFileReaderErrors.UnsupportedVariant);
            }

            numBitsOut         = numBits;
            numChannelsOut     = numChannels;
            numSampleFramesOut = numSampleFrames;
            samplingRateOut    = samplingRate;

            stream.Seek(audioDataOffset, SeekOrigin.Begin);
        }
Example #13
0
        /* this routine asks for a file and tries to import the contents of that */
        /* file as an AIFF sample.  it reports any errors to the user. */
        public static bool ImportAIFFSample(
            Registration registration,
            IMainWindowServices mainWindow,
            out int index)
        {
            index = -1;

            string path;

            using (OpenFileDialog dialog = new OpenFileDialog())
            {
                dialog.Title  = "Import AIFF Sample";
                dialog.Filter = "AIFF Audio File (.aif, .aiff)|*.aif;*.aiff|Any File Type (*)|*";
                DialogResult result = dialog.ShowDialog();
                if (result != DialogResult.OK)
                {
                    return(false);
                }
                path = dialog.FileName;
            }

            using (Stream input = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, Constants.BufferSize))
            {
                try
                {
                    using (AudioFileReader reader = new AIFFReader(input, true /*allowTruncated*/))
                    {
                        NumBitsType     numBits      = reader.NumBits;
                        NumChannelsType numChannels  = reader.NumChannels;
                        int             numFrames    = reader.NumFrames;
                        int             samplingRate = reader.SamplingRate;

                        float[] sampleData;
                        try
                        {
                            sampleData = new float[(numFrames + 1) * reader.PointsPerFrame];
                        }
                        catch (OutOfMemoryException)
                        {
                            throw new AudioFileReaderException(AudioFileReaderErrors.OutOfMemory);
                        }

                        reader.ReadPoints(sampleData, 0, numFrames * reader.PointsPerFrame);

                        if (reader.Truncated)
                        {
                            const string ErrorTooShort = "The file appears to be incomplete. Appending silence to end of sample data.";
                            MessageBox.Show(ErrorTooShort, "Import Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        }

                        SampleObjectRec ReturnedSampleObject = new SampleObjectRec(
                            mainWindow.Document,
                            sampleData,
                            numFrames,
                            numBits,
                            numChannels,
                            0,
                            0,
                            0,
                            0,
                            0,
                            0,
                            0,
                            samplingRate,
                            Constants.MIDDLEC);
                        ReturnedSampleObject.Name = Path.GetFileName(path);

                        index = mainWindow.Document.SampleList.Count;
                        mainWindow.Document.SampleList.Add(ReturnedSampleObject);

                        new SampleWindow(registration, ReturnedSampleObject, mainWindow).Show();

                        return(true);
                    }
                }
                catch (AudioFileReaderException exception)
                {
                    MessageBox.Show(AudioFileReaderException.MessageFromError(exception.Error), "Import Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }

            return(false);
        }
Example #14
0
        public static OutputGeneric <T, U, W> Do(
            string baseName,
            GetDestinationMethod <T> getDestination,
            CreateDestinationHandlerMethod <T, W> createDestinationHandler,
            W destinationHandlerParams,
            GeneratorMainLoopMethod <T, U, W> generatorMainLoop,
            U generatorParams,
            GeneratorCompletionMethod <U> generatorCompletion,
            NumChannelsType channels,
            NumBitsType bits,
            int samplingRate,
            int oversamplingFactor,
            bool showProgressWindow,
            bool modal) // modal is only meaningful when showProgressWindow==true
        {
            // set up processing record

            OutputGeneric <T, U, W> state = new OutputGeneric <T, U, W>();

            state.channels           = channels;
            state.bits               = bits;
            state.samplingRate       = samplingRate;
            state.oversamplingFactor = oversamplingFactor;

            state.totalSampleCount          = 0;
            state.clippedSampleCount        = 0;
            state.maxClipExtent             = 0;
            state.oversamplingSkipCarryover = 0;


            if ((state.bits == NumBitsType.eSample8bit) || (state.bits == NumBitsType.eSample16bit))
            {
                if (OutputGeneric <T, U, W> .UseHPTRI) // TODO: add dither selector to global settings
                {
                    state.ditherState = new Synthesizer.StereoDither_HPTRI(bits);
                }
                else
                {
                    state.ditherState = new Synthesizer.StereoDither_TPDF(bits);
                }
            }

            if (!getDestination(out state.destination))
            {
                return(null);
            }

            state.createDestinationHandler = createDestinationHandler;

            state.generatorMainLoop   = generatorMainLoop;
            state.generatorParams     = generatorParams;
            state.generatorCompletion = generatorCompletion;

            state.destinationHandlerParams = destinationHandlerParams;

            state.stopper = new Synthesizer.StopTask();

            state.waitFinishedHelper = new WaitFinishedHelper();


            // All synth parameter initialization must be done by this point to avoid race conditions!!!
            state.thread = new Thread(ThreadMain);
            state.thread.Start(state);


            if (showProgressWindow)
            {
                state.progressWindow = new OutputProgressWindow(
                    baseName,
                    true /*show clipping*/,
                    state,
                    state,
                    state.stopper,
                    state.waitFinishedHelper,
                    state.waitFinishedHelper,
                    delegate()
                {
                    ClipInfo clipInfo = new ClipInfo(
                        state.totalSampleCount,
                        state.clippedSampleCount,
                        state.maxClipExtent);

                    state.generatorCompletion(
                        generatorParams,
                        ref clipInfo);
                });
                if (modal)
                {
                    state.progressWindow.ShowDialog();
                    state.Dispose(); // suppress finalize
                }
                else
                {
                    state.progressWindow.Show();
                    // client required to dispose after completion
                }
            }

            // After this, the dialog prevents UI interaction with the application on the main thread
            // and the rendering thread does it's thing until finished.
            // The dialog and the rendering thread talk to each other about stopping and completion.

            return(state);
        }
Example #15
0
        /* AIFF/AIFF-C File Format: */
        /*     "FORM" */
        /*     4-byte big endian form chunk length descriptor (minus 8 for "FORM" & this) */
        /*     4-byte type */
        /*        "AIFF" = AIFF format file */
        /*        "AIFC" = AIFF-C format file */
        /* in any order, these chunks can occur: */
        /*   Version Chunk (this only occurs in AIFF-C files) */
        /*     "FVER" */
        /*     4-byte big endian length, which should always be the value 4 (four) */
        /*     4-byte date code.  this is probably 0xA2805140 (stored big endian), but it */
        /*          probably doesn't matter. */
        /*   Common Chunk for AIFF files */
        /*     "COMM" */
        /*     4-byte big endian length. */
        /*        always 18 for AIFF files */
        /*     2-byte big endian number of channels */
        /*     4-byte big endian number of sample frames */
        /*     2-byte big endian number of bits per sample */
        /*        a value in the domain 1..32 */
        /*     10-byte extended precision number of frames per second */
        /*   Common Chunk for AIFF-C files */
        /*     "COMM" */
        /*     4-byte big endian length. */
        /*        22 + compression method string length for AIFF-C files */
        /*     2-byte big endian number of channels */
        /*     4-byte big endian number of sample frames */
        /*     2-byte big endian number of bits per sample */
        /*        a value in the domain 1..32 */
        /*     10-byte extended precision number of frames per second */
        /*     4-byte character code ID for the compression method */
        /*        "NONE" means there is no compression method used */
        /*     some characters in a string identifying the compression method */
        /*        this must be padded to an even number of bytes, but the pad is */
        /*        NOT included in the length descriptor for the chunk. */
        /*        for uncompressed data, the string should be */
        /*        "\x0enot compressed\x00", including the null, for 16 bytes. */
        /*        the total chunk length is thus 38 bytes. */
        /*   Sound Data Chunk */
        /*     "SSND" */
        /*     4-byte big endian number of bytes in sample data array */
        /*     4-byte big endian offset to the first byte of sample data in the array */
        /*     4-byte big endian number of bytes to which the sound data is aligned. */
        /*     any length vector of raw sound data. */
        /*        this must be padded to an even number of bytes, but the pad is */
        /*        NOT included in the length descriptor for the chunk. */
        /*        Samples are stored in an integral number of bytes, the smallest that */
        /*        is required for the specified number of bits.  If this is not an even */
        /*        multiple of 8, then the data is shifted left and the low bits are zeroed */
        /*        Multichannel sound is interleaved with the left channel first. */
        private static void SetUpAIFFHeader(
            Stream outputStream,
            NumChannelsType channels,
            NumBitsType bits,
            int samplingRate)
        {
            using (BinaryWriter writer = new BinaryWriter(outputStream))
            {
                /* 0..3 */
                /*     "FORM" */
                writer.WriteFixedStringASCII(4, "FORM");

                /* 4..7 */
                /*     4-byte big endian form chunk length descriptor (minus 8 for "FORM" & this) */
                writer.WriteInt32BigEndian(0); /* RESOLVED LATER */

                /* 8..11 */
                /*     4-byte type */
                /*        "AIFC" = AIFF-C format file */
                writer.WriteFixedStringASCII(4, "AIFF");

                /* 12..15 */
                /*     "COMM" */
                writer.WriteFixedStringASCII(4, "COMM");

                /* 16..19 */
                /*     4-byte big endian length. */
                /*        always 18 for AIFF files */
                writer.WriteInt32BigEndian(18);

                /* 20..21 */
                /*     2-byte big endian number of channels */
                writer.WriteInt16BigEndian(channels == NumChannelsType.eSampleStereo ? (short)2 : (short)1);

                /* 22..25 */
                /*     4-byte big endian number of sample frames */
                writer.WriteInt32BigEndian(0); /* RESOLVED LATER */

                /* 26..27 */
                /*     2-byte big endian number of bits per sample */
                /*        a value in the domain 1..32 */
                switch (bits)
                {
                default:
                    Debug.Assert(false);
                    throw new ArgumentException();

                case NumBitsType.eSample8bit:
                    writer.WriteInt16BigEndian(8);
                    break;

                case NumBitsType.eSample16bit:
                    writer.WriteInt16BigEndian(16);
                    break;

                case NumBitsType.eSample24bit:
                    writer.WriteInt16BigEndian(24);
                    break;
                }

                /* 28..37 */
                /*     10-byte extended precision number of frames per second */
                /* extended 22050 = 400D AC44000000000000 */
                /* extended 22051 = 400D AC46000000000000 */
                /* extended 44100 = 400E AC44000000000000 */
                /* extended 44101 = 400E AC45000000000000 */
                uint exponent = 0x401e;
                uint mantissa = (uint)samplingRate;
                while ((mantissa & 0x80000000) == 0)
                {
                    mantissa  = mantissa << 1;
                    exponent -= 1;
                }
                byte[] extended = new byte[10];
                extended[0] = (byte)((exponent >> 8) & 0xff);
                extended[1] = (byte)(exponent & 0xff);
                extended[2] = (byte)((mantissa >> 24) & 0xff);
                extended[3] = (byte)((mantissa >> 16) & 0xff);
                extended[4] = (byte)((mantissa >> 8) & 0xff);
                extended[5] = (byte)(mantissa & 0xff);
                extended[6] = 0;
                extended[7] = 0;
                extended[8] = 0;
                extended[9] = 0;
                writer.WriteRaw(extended, 0, extended.Length);

                /* 38..41 */
                /*     "SSND" */
                writer.WriteFixedStringASCII(4, "SSND");

                /* 42..45 */
                /*     4-byte big endian number of bytes in sample data array */
                writer.WriteInt32BigEndian(0); /* RESOLVED LATER */

                /* 46..49 */
                /*     4-byte big endian offset to the first byte of sample data in the array */
                writer.WriteInt32BigEndian(0);

                /* 50..53 */
                /*     4-byte big endian number of bytes to which the sound data is aligned. */
                writer.WriteInt32BigEndian(0);

                /*     any length vector of raw sound data. */
                /*        this must be padded to an even number of bytes, but the pad is */
                /*        NOT included in the length descriptor for the chunk. */
                /*        Samples are stored in an integral number of bytes, the smallest that */
                /*        is required for the specified number of bits.  If this is not an even */
                /*        multiple of 8, then the data is shifted left and the low bits are zeroed */
                /*        Multichannel sound is interleaved with the left channel first. */
            }
        }
        public static void TryImportRaw(
            string path,
            int?truncate,
            int initialSkip,
            int framePadding,
            NumChannelsType channels,
            ImportBits bits,
            SignModeType signing,
            EndianType endianness,
            out float[] data,
            out int NumFrames,
            out bool endedOnFrameBoundary)
        {
            data = null;

            using (Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, Constants.BufferSize))
            {
                int channelCount = (channels == NumChannelsType.eSampleStereo ? 2 : 1);
                int bytesPerPoint;
                switch (bits)
                {
                default:
                    Debug.Assert(false);
                    throw new ArgumentException();

                case ImportBits.eSample8bit:
                    bytesPerPoint = 1;
                    break;

                case ImportBits.eSample16bit:
                    bytesPerPoint = 2;
                    break;

                case ImportBits.eSample24bit:
                    bytesPerPoint = 3;
                    break;
                }
                int frameLength = channelCount * bytesPerPoint + framePadding;

                {
                    long framesL = ((stream.Length - initialSkip) + (frameLength - 1)) / frameLength;
                    if (framesL > Int32.MaxValue)
                    {
                        throw new ArgumentOutOfRangeException();
                    }
                    NumFrames = (int)framesL;
                }
                endedOnFrameBoundary = NumFrames * frameLength + initialSkip == stream.Length;
                if (truncate.HasValue)
                {
                    NumFrames = Math.Min(NumFrames, truncate.Value);
                }

                data = new float[(NumFrames + 1) * channelCount];

                stream.Position = initialSkip;

                TranslateMethod translate;
                switch (bits)
                {
                default:
                    Debug.Assert(false);
                    throw new ArgumentException();

                case ImportBits.eSample8bit:
                    translate = Translate_8bit;
                    break;

                case ImportBits.eSample16bit:
                    switch (endianness)
                    {
                    default:
                        Debug.Assert(false);
                        throw new ArgumentException();

                    case EndianType.eEndianBig:
                        translate = Translate_16bit_big;
                        break;

                    case EndianType.eEndianLittle:
                        translate = Translate_16bit_little;
                        break;
                    }
                    break;

                case ImportBits.eSample24bit:
                    switch (endianness)
                    {
                    default:
                        Debug.Assert(false);
                        throw new ArgumentException();

                    case EndianType.eEndianBig:
                        translate = Translate_24bit_big;
                        break;

                    case EndianType.eEndianLittle:
                        translate = Translate_24bit_little;
                        break;
                    }
                    break;
                }

                ResignMethod resign;
                switch (signing)
                {
                default:
                    Debug.Assert(false);
                    throw new ArgumentException();

                case SignModeType.eSignSigned:
                    resign = Resign_Signed;
                    break;

                case SignModeType.eSignUnsigned:
                    resign = Resign_Unsigned;
                    break;

                case SignModeType.eSignSignBit:
                    resign = Resign_SignBit;
                    break;
                }

                bool terminate = false;
                for (int iFrame = 0; !terminate && iFrame < NumFrames; iFrame++)
                {
                    byte[] frame = new byte[frameLength]; // zeroed each time

                    int c = stream.Read(frame, 0, frameLength);
                    if (c != frameLength)
                    {
                        terminate = true;
                        Debug.Assert(!endedOnFrameBoundary);
                    }

                    switch (channels)
                    {
                    default:
                        Debug.Assert(false);
                        throw new ArgumentException();

                    case NumChannelsType.eSampleMono:
                        data[iFrame] = Convert(resign(translate(frame, 0)));
                        break;

                    case NumChannelsType.eSampleStereo:
                        data[2 * iFrame + 0] = Convert(resign(translate(frame, 0)));
                        data[2 * iFrame + 1] = Convert(resign(translate(frame, bytesPerPoint)));
                        break;
                    }
                }
            }
        }
Example #17
0
        /* update various size fields in the file */
        private static void ResolveWAVHeader(
            Stream output,
            long start,
            int totalFrameCount,
            NumChannelsType channels,
            NumBitsType bits)
        {
            byte[] buffer = new byte[4];

            int totalBytesOfSamples = totalFrameCount;

            if (channels == NumChannelsType.eSampleStereo)
            {
                totalBytesOfSamples *= 2;
            }
            switch (bits)
            {
            default:
                Debug.Assert(false);
                throw new ArgumentException();

            case NumBitsType.eSample8bit:
                break;

            case NumBitsType.eSample16bit:
                totalBytesOfSamples *= 2;
                break;

            case NumBitsType.eSample24bit:
                totalBytesOfSamples *= 3;
                break;
            }

            /* make sure file is an even number of bytes */
            if (((output.Position - start) & 1) != 0)
            {
                output.WriteByte(0);
            }

            /* chop off any crud from the end */
            output.SetLength(output.Position);

            /* 4..7 */
            /*  4-byte little endian length descriptor (minus 8 bytes for these 2 fields) */
            output.Position = start + 4;
            buffer[0]       = (byte)((totalBytesOfSamples + 36) & 0xff);
            buffer[1]       = (byte)(((totalBytesOfSamples + 36) >> 8) & 0xff);
            buffer[2]       = (byte)(((totalBytesOfSamples + 36) >> 16) & 0xff);
            buffer[3]       = (byte)(((totalBytesOfSamples + 36) >> 24) & 0xff);
            output.Write(buffer, 0, 4);

            /* 40..43 */
            /*  4-byte little endian length of sample data descriptor */
            output.Position = start + 40;
            buffer[0]       = (byte)(totalBytesOfSamples & 0xff);
            buffer[1]       = (byte)((totalBytesOfSamples >> 8) & 0xff);
            buffer[2]       = (byte)((totalBytesOfSamples >> 16) & 0xff);
            buffer[3]       = (byte)((totalBytesOfSamples >> 24) & 0xff);
            output.Write(buffer, 0, 4);

            output.Position = output.Length;
        }
Example #18
0
        /* update various size fields in the file */
        private static void ResolveAIFFHeader(
            Stream output,
            long start,
            int totalFrameCount,
            NumChannelsType channels,
            NumBitsType bits)
        {
            byte[] buffer = new byte[4];

            int totalBytesOfSamples = totalFrameCount;

            if (channels == NumChannelsType.eSampleStereo)
            {
                totalBytesOfSamples *= 2;
            }
            switch (bits)
            {
            default:
                Debug.Assert(false);
                throw new ArgumentException();

            case NumBitsType.eSample8bit:
                break;

            case NumBitsType.eSample16bit:
                totalBytesOfSamples *= 2;
                break;

            case NumBitsType.eSample24bit:
                totalBytesOfSamples *= 3;
                break;
            }

            /* make sure file is an even number of bytes */
            if (((output.Position - start) & 1) != 0)
            {
                output.WriteByte(0);
            }

            /* chop off any crud from the end */
            output.SetLength(output.Position);

            /* 4..7 */
            /*     4-byte big endian form chunk length descriptor (minus 8 for "FORM" & this) */
            output.Position = start + 4;
            buffer[0]       = (byte)(((totalBytesOfSamples + 54 - 8) >> 24) & 0xff);
            buffer[1]       = (byte)(((totalBytesOfSamples + 54 - 8) >> 16) & 0xff);
            buffer[2]       = (byte)(((totalBytesOfSamples + 54 - 8) >> 8) & 0xff);
            buffer[3]       = (byte)((totalBytesOfSamples + 54 - 8) & 0xff);
            output.Write(buffer, 0, 4);

            /* 22..25 */
            /*     4-byte big endian number of sample frames */
            output.Position = start + 22;
            buffer[0]       = (byte)((totalFrameCount >> 24) & 0xff);
            buffer[1]       = (byte)((totalFrameCount >> 16) & 0xff);
            buffer[2]       = (byte)((totalFrameCount >> 8) & 0xff);
            buffer[3]       = (byte)(totalFrameCount & 0xff);
            output.Write(buffer, 0, 4);

            /* 42..45 */
            /*     4-byte big endian number of bytes in sample data array */
            output.Position = start + 42;
            buffer[0]       = (byte)(((totalBytesOfSamples + 8) >> 24) & 0xff);
            buffer[1]       = (byte)(((totalBytesOfSamples + 8) >> 16) & 0xff);
            buffer[2]       = (byte)(((totalBytesOfSamples + 8) >> 8) & 0xff);
            buffer[3]       = (byte)((totalBytesOfSamples + 8) & 0xff);
            output.Write(buffer, 0, 4);

            output.Position = output.Length;
        }