The website "dmilvdv.narod.ru." is not registered with uCoz.
If you are absolutely sure your website must be here,
please contact our Support Team.
If you were searching for something on the Internet and ended up here, try again:

About uCoz web-service

Community

Legal information

Общие сведения

Общие сведения

Предыдущая  Содержание  Следующая  V*D*V

При синтезе результатом работы является поток звуковых данных, которые далее можно либо проиграть, либо записать как звуковой файл.

 

PCM wav файл имеет простую структуру, состоящую из заголовка и данных.

Заголовок

Заголовок содержит информацию, позволяющую определить, как надо работать с данными.

 

wav_header = {'R', 'I', 'F', 'F',//sRIFF [4]

                  0, 0, 0, 0,//riff_size//full_size - 8

                  'W', 'A', 'V', 'E', 'f', 'm', 't', ' ',//sWAVEfmt[8]

                  0x10, 00, 00, 00,//nExt

                  0x01, 00,//wFormatTag

                  0x01, 00,//nChannels

                  0x11, 0x2B, 00, 00,//nSamplesPerSec

                  0x11, 0x2B, 00, 00,//nAvgBytesPerSec

                  0x01, 00,//nBlockAlign

                  0x08, 00,//wBitsPerSample

                  'd', 'a', 't', 'a',//sdata[4]

                  00, 00, 00, 00};//data_size//full_size - 44

 

Поля заголовка. Для всех полей младший байт - первый:

sRIFF - текстовое поле "RIFF". 4 байта.

RIFF size - 4 байта, определяющие размер идущих дальше данных. RIFF size = полное число данных в байтах (включая заголовок) - 8.

sWAVEfmt - текстовое поле "WAVEfmt ", 8 байт.

nExt - дополнительное поле. 4 байта. Для PCM файла 0x00000010.

wFormatTag - поле, определяющее алгоритм компрессии. 2 байта. Для PCM файла 0x00000001.

nChannels - число каналов. 2 байта.

nSamplesPerSec - число сэмплов в секунду. 4 байта. nSamplesPerSec = частота дискретизации.

nAvgBytesPerSec - число байтов в секунду. 4 байта. nAvgBytesPerSec = частота дискретизации * число каналов * ( число бит в сэмпле / 8 ).

nBlockAlign - число байтов на блок данных. 2 байта. nBlockAlign = число бит в сэмпле / 8 * число каналов.

wBitsPerSample - число битов в сэмпле. 2 байта.

sdata - текстовое поле "data". 4 байта.

data size - размер данных. data size = полное число данных в байтах (включая заголовок) - 44.

Звук

Звуковые данные располагаются после заголовка и представляют собой просто числовые значения отсчетов.

Для 8-ми битных данных средним уровнем считается число 128. Таким образом, числу 0 соответствует -128 (минимальное значение), числу 255 соответствует 127 (максимальное значение).

Для 16-ти битных данных средним уровнем считается число 0. Таким образом, -32768 - минимальное значение, 32767 - максимальное.

 

Пример, стерео, 16 бит:

л1, п1, л2, п2, л3, п3...

Реализация

public final class Snd

{

   private static int m_sampleRate = 32000;

   //

   //private static final int RIFF = 0;

  private static final int RIFF_SIZE = 4;

  //private static final int WAVE_FMT = 8;

  //private static final int EXT = 16;

  //private static final int FORMAT_TAG = 20;

  private static final int CHANNELS = 22;

  private static final int SAMPLES_PER_SEC = 24;

  private static final int AVG_BYTES_PER_SEC = 28;

  private static final int BLOCK_ALIGN = 32;

  private static final int BITS_PER_SAMPLE = 34;

  //private static final int SDATA = 36;

  private static final int DATA_SIZE = 40;

  private static byte[] wav_header = {'R', 'I', 'F', 'F',//sRIFF [4]

                           0, 0, 0, 0,//riff_size//full_size - 8

                          'W', 'A', 'V', 'E', 'f', 'm', 't', ' ',//sWAVEfmt[8]

                           0x10, 00, 00, 00,//nExt

                           0x01, 00,//wFormatTag

                           0x01, 00,//nChannels

                           0x11, 0x2B, 00, 00,//nSamplesPerSec

                           0x11, 0x2B, 00, 00,//nAvgBytesPerSec

                           0x01, 00,//nBlockAlign

                           0x08, 00,//wBitsPerSample

                          'd', 'a', 't', 'a',//sdata[4]

                           00, 00, 00, 00};//data_size//full_size - 44

  //

  public static void setSoundFormat(int sampleRate, int bitPerSample, int channels) {

       m_sampleRate = sampleRate;

      valueToByte( sampleRate, 4, wav_header, SAMPLES_PER_SEC );

      valueToByte( sampleRate * channels * ( bitPerSample / 8 ), 4, wav_header, AVG_BYTES_PER_SEC );

      valueToByte( bitPerSample, 2, wav_header, BITS_PER_SAMPLE );

      valueToByte( bitPerSample * channels / 8, 2, wav_header, BLOCK_ALIGN );

      valueToByte( channels, 2, wav_header, CHANNELS );

   }

  public static int getSampleRate() { return m_sampleRate; }

  public static void valueToByte(long value, int byteCount, byte[] data, int offset) {

       for(int i = 0; i < byteCount; i++)

           data[offset++] = (byte) (value >> (i << 3));

   }

  public static void writeHeader(byte[] snd) {

       System.arraycopy( wav_header, 0, snd, 0, wav_header.length );

       Snd.valueToByte( snd.length - 8, 4, snd, RIFF_SIZE );

       Snd.valueToByte( snd.length - wav_header.length, 4, snd, DATA_SIZE );

   }

   public static byte[] toSndStream(short[] d) {

       byte[] b = new byte[d.length * 2 + wav_header.length];

       for( int i = wav_header.length, k = 0; i < b.length; ) {

           int s = (int)d[k++];

           b[i++] = (byte)s;

           b[i++] = (byte)(s>>8);

       }

       Snd.writeHeader( b );

       return b;

  }

  public static byte[] toSndStream(double[] d) {

       byte[] b = new byte[d.length * 2 + wav_header.length];

       for( int i = wav_header.length, k = 0; i < b.length; ) {

           int s = (int)d[k++];

           b[i++] = (byte)s;

           b[i++] = (byte)(s>>8);

       }

       Snd.writeHeader( b );

       return b;

  }

}

 

Предыдущая  Содержание  Следующая