Adpcm кодирование на Java

Тема в разделе "Java", создана пользователем Eugene881118, 8 июл 2008.

  1. Eugene881118

    Eugene881118 Гость

    Репутация:
    0
    нужно сделать программу перекодировки wav файла в bin используя алгоритм ADPCM. есть этот алгоритм написанный на яве
    Код:

    Код:
    package transform.contrib; 
    
    import com.flagstone.transform.FSCoder; 
    
    import java.lang.*; 
    import java.io.*; 
    
    /** 
    * The ADPCM class can be used to compress PCM encoded sounds to the more 
    * efficient ADPCM format. ADPCM is a compressed format and Flash supports a 
    * modified ADPCM algorithm with compressed samples taking 2, 3, 4 or 5 bits. 
    * This results in much smaller file sizes when a movie is encoded. 
    * 
    * <b>Examples</b> 
    * 
    * The following code sample illustrates how to use the ADPCM class to add 
    * sounds to a Flash file. 
    * 
    * int soundId = movie.newIdentifier(); 
    * int compressedSize = 5; 
    * 
    * FSSoundConstructor soundGenerator = new FSSoundConstructor("sound.wav"); 
    * 
    * int channelCount = soundGenerator.getNumberOfChannels(); 
    * int sampleCount = soundGenerator.getSamplesPerChannel(); 
    * int sampleRate = soundGenerator.getSamplesRate(); 
    * int sampleSize = soundGenerator.getSamplesSize(); 
    * 
    * byte[] compressedSound = ADPCM.compress(soundGenerator.getSound(), 
    *	 channelCount, sampleSize, compressedSize); 
    * 
    * soundGenerator.setSound(FSSound.ADPCM, channelCount, sampleCount, sampleRate, 
    *	 sampleSize, compressedSound); 
    * 
    * movie.add(soundGenerator.defineSound(soundId)); 
    * movie.add(new FSStartSound(FSSound(soundId, FSSound.Start))); 
    * 
    */ 
    public final class ADPCM 
    { 
    private static final int[] StepSize = 
    { 
    7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 
    19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 
    50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 
    130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 
    337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 
    876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 
    2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 
    5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 
    15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 
    }; 
    
    private static final int[][] DeltaTable = 
    { 
    { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 
    { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 
    { -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 
    { -1, -1, 2, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, 
    { -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1 }, 
    { -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16 }, 
    }; 
    
    
    /** 
    * Compresses a little-endian, PCM format sound to ADPCM. This method should 
    * only be used with sounds in the FSSound.PCM format since the byte-order 
    * in FSSound.NATIVE_PCM is platform dependent. 
    * 
    * @param sound an array of bytes containing the sound samples. 
    * 
    * @param numberOfChannels the number of channels in the sound, typically 
    * 1 (mono) or 2 (stereo). 
    * 
    * @param sampleSize the size of each sound sample in bytes, typically 1 or 2. 
    * 
    * @param compressedSize the number of bits to compress each sound sample to. 
    * Flash supports sample sizes in the range 2..5 bits. 
    * 
    * @return an array of bytes containing the compressed sound. 
    */ 
    public static byte[] compress(byte[] sound, int numberOfChannels, int sampleSize, int compressedSize) 
    { 
    int samplesPerFrame = 4096; 
    
    // Calculate size of encoded data 
    
    int numberOfSamples = sound.length / sampleSize; 
    int samplesPerChannel = numberOfSamples / numberOfChannels; 
    int numberOfFrames = (samplesPerChannel + 4095) / 4096; 
    
    int frameSize = (16 + 6 + samplesPerFrame * compressedSize) * numberOfChannels; 
    int lastFrameSize = (16 + 6 + (samplesPerChannel % samplesPerFrame) * compressedSize) * numberOfChannels; 
    int bytesPerFrame = (frameSize + 7) >> 3; 
    
    byte[] out = new byte[numberOfFrames*bytesPerFrame]; 
    
    /* 
    * Expand the sound data to 16-bit samples. 
    */ 
    int[] samples = new int[numberOfSamples]; 
    
    FSCoder soundIn = new FSCoder(FSCoder.LITTLE_ENDIAN, sound); 
    
    for (int i=0; i<numberOfSamples; i++) 
    samples[i] = soundIn.readWord(sampleSize*8, true); 
    
    /*			 ВЫЛЕТАЕТ ТУТ 
    * Allocate an initialize arrays to hold value, the index into the step 
    * size table and the step size for the current sample in each channel. 
    */ 
    int[] value = new int[numberOfChannels]; 
    int[] tableIndex = new int[numberOfChannels]; 
    int[] step = new int[numberOfChannels]; 
    
    for (int chan=0; chan<numberOfChannels; chan++) 
    { 
    value[chan] = 0; 
    tableIndex[chan] = 0; 
    step[chan] = 0; 
    } 
    
    int currentSample = 0; 
    
    FSCoder compressedData = new FSCoder(FSCoder.LITTLE_ENDIAN, new byte[numberOfSamples*sampleSize]); 
    
    /* 
    * ADPCM encoded sounds in Flash start with a 2-bit field contains the 
    * number of bits per sample minus 2. 
    */ 
    compressedData.writeBits(compressedSize-2, 2); 
    
    for (int i=0; i<samplesPerChannel-1; i++) 
    { 
    if (i % 4096 == 0) // start a new packet every 4096 samples 
    { 
    compressedData.alignToByte(); 
    
    for (int chan=0; chan<numberOfChannels; chan++, currentSample++) 
    { 
    value[chan] = samples[currentSample]; 
    
    int diff = Math.abs(samples[currentSample+numberOfChannels] - value[chan]); 
    
    // Calculate initial index & step 
    
    int index = 0; 
    
    while (StepSize[index] < diff && index < 63) 
    index ++; 
    
    tableIndex[chan] = index; 
    step[chan] = StepSize[index]; 
    
    // Write initial index into StepSizeTable 
    
    compressedData.writeBits(value[chan], 16); 
    compressedData.writeBits(tableIndex[chan], 6); 
    } 
    } 
    else 
    { 
    for (int chan=0; chan<numberOfChannels; chan++, currentSample++) 
    { 
    // Step 1 - compute difference with previous value 
    
    int diff = samples[currentSample] - value[chan]; 
    int sign = (diff < 0) ? (1 << (compressedSize-1)) : 0; 
    
    if (sign > 0) diff = (-diff); 
    
    // Step 2 - Divide and clamp 
    int delta = 0; 
    int vpdiff = step[chan] >> (compressedSize-1); 
    
    for (int j=compressedSize-2; j>=0; j--, step[chan] >>= 1) 
    { 
    if (diff >= step[chan]) 
    { 
    delta = delta | (1 << j); 
    vpdiff += step[chan]; 
    
    if (j > 0) 
    diff -= step[chan]; 
    } 
    } 
    
    // Step 3 - Update previous value 
    if (sign > 0) 
    value[chan] -= vpdiff; 
    else 
    value[chan] += vpdiff; 
    
    // Step 4 - Clamp previous value to 16 bits 
    if (value[chan] > 32767) value[chan] = 32767; 
    if (value[chan] < -32768) value[chan] = -32768; 
    
    // Step 5 - Assemble value, update index and step values 
    
    tableIndex[chan] += DeltaTable[compressedSize][delta]; 
    
    // Clamp StepSizeTable index 
    if (tableIndex[chan] < 0) tableIndex[chan] = 0; 
    if (tableIndex[chan] > 88) tableIndex[chan] = 88; 
    
    step[chan] = StepSize[tableIndex[chan]]; 
    
    // Step 6 - Output value 
    compressedData.writeBits(delta |= sign, compressedSize); 
    } 
    } 
    } 
    
    int compressedLength = compressedData.getPointer() / 8; 
    
    for (int i=0; i<compressedLength; i++) 
    out[i] = compressedData.getData()[i]; 
    
    return out; 
    }

    вот ссылка на это http://www.koders.com/java/fid26A9A93D3BEC...53ADAFC5C5.aspx
    при выполнении вылетает ошибка:
    java.lang.IllegalArgumentException: Number of bytes must be in the range 1..4.
    на другом форуме по яве посоветовали просто в строке
    Код:
    samples[i] = soundIn.readWord(sampleSize*8, true);
    убрать умножение на 8 но после этого (или независимо) получается выход за границы индекса массива в строке
    Код:
    tableIndex[chan] += DeltaTable[compressedSize][delta];
    стэк трейс :
    java.lang.ArrayIndexOutOfBoundsException: 5324
    at transform.contrib.ADPCM.compress(ADPCM.java:248)
    at transform.contrib.ADPCM.main(ADPCM.java:281)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.jav
    a:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:86)


    яву изучаю второй день. незнаю что делать.
     
Загрузка...
Похожие Темы - Adpcm кодирование на
  1. Akerlem
    Ответов:
    1
    Просмотров:
    1.260
  2. Dios1986
    Ответов:
    17
    Просмотров:
    4.765

Поделиться этой страницей