Exemple #1
0
            /* initialize the dither structure */
            public StereoDither_TPDF(
                NumBitsType Precision)
            {
                this.Left.Seed1  = new ParkAndMiller(1);
                this.Left.Seed2  = new ParkAndMiller(2);
                this.Right.Seed1 = new ParkAndMiller(3);
                this.Right.Seed2 = new ParkAndMiller(4);

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

                case NumBitsType.eSample8bit:
                    this.Left.Scale1 = .5f / SampConv.FLOATFACTOR8BIT;
                    this.Left.Scale2 = .25f / SampConv.FLOATFACTOR8BIT;
                    break;

                case NumBitsType.eSample16bit:
                    this.Left.Scale1 = .5f / SampConv.FLOATFACTOR16BIT;
                    this.Left.Scale2 = .25f / SampConv.FLOATFACTOR16BIT;
                    break;

                case NumBitsType.eSample24bit:
                    // shouldn't bother dithering for 24 bits
                    Debug.Assert(false);
                    throw new ArgumentException();
                }
                this.Right.Scale1 = this.Left.Scale1;
                this.Right.Scale2 = this.Left.Scale2;
            }
Exemple #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);
        }
        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);
        }
 public static DestinationHandler <OutputSelectableFileDestination> CreateOutputSelectableFileDestinationHandler(
     OutputSelectableFileDestination destination,
     NumChannelsType channels,
     NumBitsType bits,
     int samplingRate,
     OutputSelectableFileArguments arguments)
 {
     return(new OutputSelectableFileDestinationHandler(
                destination.path,
                channels,
                bits,
                samplingRate,
                arguments));
 }
Exemple #5
0
 public WaveTableTestGeneratorParams(
     WaveTableStorageRec data,
     double attack,
     double decay,
     NumBitsType numBits,
     int samplingRate,
     double frequency)
 {
     this.data = data;
     this.attack = attack;
     this.decay = decay;
     this.numBits = numBits;
     this.samplingRate = samplingRate;
     this.frequency = frequency;
 }
Exemple #6
0
 bool IMenuStripManagerHandler.ExecuteMenuItem(MenuStripManager menuStrip, ToolStripMenuItem menuItem)
 {
     if (menuItem == menuStrip.buildObjectToolStripMenuItem)
     {
         BuildThis(true /*force*/);
         return(true);
     }
     else if (menuItem == menuStrip.disassembleToolStripMenuItem)
     {
         DisassembleThis();
         return(true);
     }
     else if (menuItem == menuStrip.openAsSampleToolStripMenuItem)
     {
         if (BuildThis(false /*force*/))
         {
             NumBitsType numBits = NumBitsType.Max;
             float[]     buffer  = (float[])algoSampObject.SampleData.Buffer.Clone();
             SampConv.QuantizeAndClampVector(buffer, numBits); // ensure target bit depth is honored
             SampleObjectRec sampleObject = new SampleObjectRec(
                 mainWindow.Document,
                 buffer,
                 algoSampObject.SampleData.NumFrames,
                 numBits,
                 algoSampObject.NumChannels,
                 algoSampObject.Origin,
                 algoSampObject.LoopStart1,
                 algoSampObject.LoopStart2,
                 algoSampObject.LoopStart3,
                 algoSampObject.LoopEnd1,
                 algoSampObject.LoopEnd2,
                 algoSampObject.LoopEnd3,
                 algoSampObject.SamplingRate,
                 algoSampObject.NaturalFrequency);
             sampleObject.Name = String.Format("Copy of {0}", algoSampObject.Name);
             mainWindow.Document.SampleList.Add(sampleObject);
             new SampleWindow(registration, sampleObject, mainWindow).Show();
         }
         return(true);
     }
     else if (menuItem == menuStrip.deleteObjectToolStripMenuItem)
     {
         Close();
         mainWindow.DeleteObject(algoSampObject, mainWindow.Document.AlgoSampList);
         return(true);
     }
     return(false);
 }
        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;
 }
Exemple #9
0
        public static void QuantizeAndClampVector(float[] vector, NumBitsType bits)
        {
            switch (bits)
            {
            default:
                Debug.Assert(false);
                throw new InvalidOperationException();

            case NumBitsType.eSample8bit:
                for (int i = 0; i < vector.Length; i++)
                {
                    float v  = vector[i];
                    float v2 = SignedByteToFloat(FloatToSignedByte(vector[i]));
                    Debug.Assert(v2 == SignedByteToFloat(FloatToSignedByte(vector[i])));     // verify conversion idempotency (i.e. stability)
                    vector[i] = v2;
                }
                break;

            case NumBitsType.eSample16bit:
                for (int i = 0; i < vector.Length; i++)
                {
                    float v  = vector[i];
                    float v2 = SignedShortToFloat(FloatToSignedShort(vector[i]));
                    Debug.Assert(v2 == SignedShortToFloat(FloatToSignedShort(vector[i])));     // verify conversion idempotency (i.e. stability)
                    vector[i] = v2;
                }
                break;

            case NumBitsType.eSample24bit:
                for (int i = 0; i < vector.Length; i++)
                {
                    float v  = vector[i];
                    float v2 = SignedTribyteToFloat(FloatToSignedTribyte(vector[i]));
                    Debug.Assert(v2 == SignedTribyteToFloat(FloatToSignedTribyte(vector[i])));     // verify conversion idempotency (i.e. stability)
                    vector[i] = v2;
                }
                break;
            }
        }
Exemple #10
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;
            }
        }
Exemple #11
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;
            }
Exemple #12
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. */
            }
        }
Exemple #13
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);
        }
Exemple #14
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);
        }
Exemple #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 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);
        }
        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);
        }
Exemple #17
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. */
            }
        }
Exemple #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;
        }
Exemple #19
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;
        }