Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 5.00/55: Рейтинг темы: голосов - 55, средняя оценка - 5.00
84 / 4 / 0
Регистрация: 01.02.2012
Сообщений: 93

Считывание массива семплов из WAV

21.06.2015, 01:27. Показов 12687. Ответов 52
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! Такая проблема. Считывается заголовок. Когда пытаюсь считать поле data в массив, чтобы получить значения амплитуд звука получаю segmentation fault. Не могли бы вы написать, как считать сами значения? (в матлабе считывает все стандартная функция и такой проблемы нет)

Пример брала отсюда http://audiocoding.ru/article/... cture.html

Мой код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <math.h>
 
using namespace std;
 
struct  WAV_HEADER{
        char                RIFF[4];        // RIFF Header      Magic header
        unsigned long       ChunkSize;      // RIFF Chunk Size
        char                WAVE[4];        // WAVE Header
        char                fmt[4];         // FMT header
        unsigned long       Subchunk1Size;  // Size of the fmt chunk
        unsigned short      AudioFormat;    // Audio format 1=PCM,6=mulaw,7=alaw, 257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM
        unsigned short      NumOfChan;      // Number of channels 1=Mono 2=Sterio
        unsigned long       SamplesPerSec;  // Sampling Frequency in Hz
        unsigned long       bytesPerSec;    // bytes per second
        unsigned short      blockAlign;     // 2=16-bit mono, 4=16-bit stereo
        unsigned short      bitsPerSample;  // Number of bits per sample
        char                Subchunk2ID[4]; // "data"  string
        unsigned long       Subchunk2Size;  // Sampled data length
 
    //std::vector<long double> data;
    std::vector<char*> data;
    };
 
struct WAV_DATA{
 
    std::vector<long> data;
};
 
int main()
{
 
        WAV_HEADER wavHeader;
    WAV_DATA wavData;
        FILE *wavFile;
    int i=0;
 
    //wavData.data.reserve(255);
    wavHeader.data.reserve(255);
 
        long headerSize = sizeof(wavHeader), filelength = 0;
 
     wavFile = fopen ("pilotag_wav.wav", "rb");
 
     if (wavFile!=NULL)
      {
        cout << "File Open\n"; 
      } 
      else 
      {
         cout << "File no open\n"; 
      };
      
        fread(&wavHeader,headerSize,1,wavFile);
    unsigned long size = labs(wavHeader.Subchunk2Size); 
    
    printf("Number of channel = %d\n", wavHeader.NumOfChan);
    printf("Sampling Frequency = %ld\n", wavHeader.SamplesPerSec);
    printf("bits per sec = %d\n", wavHeader.bitsPerSample);
        printf("Sampled data length = %ld\n", labs(wavHeader.Subchunk2Size));
 
    
    //fread(&wavData,8,size,wavFile);  // segmfault?
        //char *pData = new char[size+1]; 
 
    //printf(" %s\n", wavHeader.data[0]);
 
    for(int i=0; i<size; i++)
    {
        cout << i<<"= " << wavHeader.data[i] << endl;
    }
 
 
        //fclose(wavFile); 
      
    return 0;
}
Добавлено через 1 час 46 минут
И как проверить там ли записываются данные заголовка, а то при выводе в консоль после RIFF идет адракадабра из символов?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.06.2015, 01:27
Ответы с готовыми решениями:

Считывание и запись Wav
Здравствуйте, подскажите, почему с таким кодом файл не остается таким же, а уменьшается размером и длительностью звучания? using...

Считывание заголовка wav файлов
Есть код: #include &lt;stdio.h&gt; #include &lt;tchar.h&gt; #include &lt;conio.h&gt; #include &lt;math.h&gt; // Структура, описывающая заголовок...

Считывание .wav + изменение частоты дискредитации
Здравствуйте. Возникла проблема с работой функции decimate и interp, хотя Signal Processing Toolbox установлен. Необходимо провести...

52
 Аватар для iRomul
163 / 104 / 14
Регистрация: 17.10.2012
Сообщений: 488
25.06.2015, 17:01
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Trisha Ray Посмотреть сообщение
C++
1
2
3
4
printf(" %s\n", wavHeader.chunkId);
printf(" %s\n", wavHeader.format);
printf(" %s\n", wavHeader.subchunk1Id);
printf(" %s\n", wavHeader.Subchunk2ID);
chunkId, format, subchunk1Id и Subchunk2ID не являются строками, оконченными нулями. Так вы их не выведете, но с другой примерно понятно, чем равно их содержимое
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,476
25.06.2015, 17:22
Цитата Сообщение от Trisha Ray Посмотреть сообщение
Помоему, сейчас в pData читается что-то странное9
более чем. не может быть столько каналов и столько бит на сэмпл.. выкиньте, простите меня, свой код и подсуньте мой - в чем проблема? хоть для пробы.
Цитата Сообщение от Trisha Ray Посмотреть сообщение
В итоге хочется прийти к массиву примерно как в матлабе
этот массив получен нормированием к некому диапазону. может к мин / макс значению файла. может еще чего. в идеале нужно почитать как это делал матлаб ибо это чисто прикладная фишка к файлу не относящаяся.
0
84 / 4 / 0
Регистрация: 01.02.2012
Сообщений: 93
25.06.2015, 17:23  [ТС]
iRomul,

Понятно, но у меня до сих пор вопрос о том, что же пишется в массив?

По статье "Рассмотрим самый обычный WAV файл. Он представляет собой две, четко делящиеся, области. Одна из них – заголовок файла, другая – область данных.
...
Амплитуда выражается числом, занимаемым в памяти (файле) 8, 16, 24, 32 бит (теоретически можно и больше). Как известно, 8 бит = 1 байту, следовательно, какая-то одна амплитуда в какой-то короткий промежуток времени в памяти (файле) может занимать 1, 2, 3, 4 байта соответственно. Таким образом, чем больше число занимает места в памяти (файле), тем больше диапазон значений для этого числа, а значит и для амплитуды."

То есть у меня в области данных должны лежать амплитуды звука в формате от -1 до +1.
В массив пишутся числа совсем на это не похожие. Что происходит?

P.S. Благодарю за уделенное мне время, а то просто не знала что делать)
0
84 / 4 / 0
Регистрация: 01.02.2012
Сообщений: 93
25.06.2015, 17:30  [ТС]
vxg,
Запустила сначала ваш, потом свой.
Изображения
 
0
84 / 4 / 0
Регистрация: 01.02.2012
Сообщений: 93
25.06.2015, 17:40  [ТС]
vxg,
В matlab: Y=wavread(FILE) — считывает файл типа WAVE с именем FILE и возвращает данные в массиве Y;

К сожалению, не нашла ничего про преобразование или нормировку.

Простым запуском этого файла получаем немного округленные значения.
Миниатюры
Считывание массива семплов из WAV  
0
84 / 4 / 0
Регистрация: 01.02.2012
Сообщений: 93
25.06.2015, 17:44  [ТС]
В матлабе использовала всегда 3 вариант, где получаю частоту и бит на отсчет.

Для этого файла FS=22050, bits=16

У меня же получается 44100 и 14
Миниатюры
Считывание массива семплов из WAV  
1
84 / 4 / 0
Регистрация: 01.02.2012
Сообщений: 93
25.06.2015, 20:13  [ТС]
Нашла пример
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <iostream> 
#include <Windows.h>
#include <fstream> 
 
 
using namespace std; 
 
 
void main(void)
{
 
 
    
    setlocale(LC_ALL,"Russian"); //Локаль
 
 
    ifstream file("C:/2.wav",ios::beg | ios::in|ios::binary); //Наша wav'ка
    if (!file) cout<<"Не удалось открыть файл"<<endl; 
 
 
    DWORD dwRIFF = 0; //И так идет формат wav-файла, он относится к RIFF-файлам, поэтому читаем 4 байта структуы
    file.read((char*) &dwRIFF,4);
    if (dwRIFF != MAKEFOURCC('R','I','F','F')) //Если RIFF не получили, то значит какую то залепу открыли
    {
        cout<<"Файл не является RIFF - formated"<<endl;
      
    }
 
 
 
 
    
    file.ignore(4); //Пропустим 4 байта там какая то охинея нам совершенно не нужна
    DWORD dwWave = 0; //Секция WAVE
    DWORD dwFormat = 0; // Секция fmt /формат файла/
    long  lSizeFmt = 0; //Размер секции fmt
    
    file.read((char*)&dwWave,4); //Читаем 4 байта, там для Wav-файла должно быть название секции WAVE
    if (dwWave != MAKEFOURCC('W','A','V','E')) //Проверим
    {
        cout<<"Файл не имеет секции WAVE"<<endl;
    
}
    
    file.read((char*)&dwFormat,4); //Если все ОК... То читаем 
    if (dwFormat != MAKEFOURCC('f','m','t',' ')) //Если секция fmt - не найдена 
    {
        cout<<"Файл не имеет Format(fmt)-Секции "<<endl;
       
    }
    file.read((char*)&lSizeFmt,4); //Еще читаем 4 байта, там у нас размер секции формат, где идет сам формат + может идти всякая охинея, формат лежит в 16 байтах
    WAVEFORMATEX WaveFormat = WAVEFORMATEX(); //Определим структуру винды
    file.read((char*)&WaveFormat,16); //Прочитаем ее
    file.ignore(lSizeFmt-16); //Пропустим охинею
    if (WaveFormat.wFormatTag != 1) //Если таг <>1 то значит есть компрессия файла, ее разбирать мы не будем, работаем не с жатыми данными
    {
        cout<<"Файл имеет компрессию"<<endl;
        
    }
    
    DWORD dwSection = 0; //Следующая секция у нас или fact(Не обязательная) или data(это как раз наш звук)
    file.read((char*)&dwSection,4); //Читаем заголовок
    if (dwSection == MAKEFOURCC('f','a','c','t')) //Если все же fact - то пропускаем ее
    {
        cout<<"Файл имеет секцию fact"<<endl;
        DWORD dwSizeFact = 0;
        file.read((char*)&dwSizeFact,4);
        file.ignore(dwSizeFact);
        file.read((char*)&dwSection,4);
    }
 
 
    if (dwSection != MAKEFOURCC('d','a','t','a')) //Ну а теперь сама data - это то, над чем мы будем работать
    {
        cout<<"Не найдена секция data"<<endl;
       
    }
    DWORD dwDataSize =0; 
    file.read((char*)&dwDataSize,4); //Прочитаем ее размер
    char *pData = new char[dwDataSize]; //Динамически выделим переменную типа char[размер звуковых данных]
 
 
    file.read(pData,dwDataSize); //Прочитаем в нее все звуковые данные
    file.close(); //Закроем файл, он нам уже не нужен, у нас есть pData
Начала оптимизировать под unix
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <stdio.h>
#include <stdlib.h>
#include <iostream> 
//#include <Windows.h>
#include <fstream> 
 
 
using namespace std; 
 
void main(void)
{
 
    ifstream file("pilotag_wav.wav",ios::beg | ios::in|ios::binary); 
    if (!file) cout<<"Не удалось открыть файл"<<endl; 
 
 
    unsigned long dwRIFF = 0; 
    file.read((char*) &dwRIFF,4);
    if (dwRIFF != MAKEFOURCC('R','I','F','F')) 
    {
        cout<<"File not RIFF - formated\n"<<endl;
      
    }
 
 
    file.ignore(4); 
    unsigned long dwWave = 0; 
    unsigned long dwFormat = 0; 
    long  lSizeFmt = 0; 
    
    file.read((char*)&dwWave,4); 
    if (dwWave != MAKEFOURCC('W','A','V','E')) 
    {
        cout<<"File hasn't WAVE section\n"<<endl;
    }
    
    file.read((char*)&dwFormat,4); 
    if (dwFormat != MAKEFOURCC('f','m','t',' ')) 
    {
        cout<<"File hasn't Format(fmt) section\n"<<endl;
       
    }
    file.read((char*)&lSizeFmt,4); 
    WAVEFORMATEX WaveFormat = WAVEFORMATEX(); 
    file.read((char*)&WaveFormat,16); 
    file.ignore(lSizeFmt-16); 
    if (WaveFormat.wFormatTag != 1) 
    {
        cout<<"File has compresion"<<endl;
        
    }
    
    unsigned long dwSection = 0; 
    file.read((char*)&dwSection,4); 
    if (dwSection == MAKEFOURCC('f','a','c','t')) 
    {
        cout<<"Файл имеет секцию fact"<<endl;
        unsigned long dwSizeFact = 0;
        file.read((char*)&dwSizeFact,4);
        file.ignore(dwSizeFact);
        file.read((char*)&dwSection,4);
    }
 
 
    if (dwSection != MAKEFOURCC('d','a','t','a')) 
    {
        cout<<"Section data not find"<<endl;
       
    }
 
    unsigned long dwDataSize =0; 
    file.read((char*)&dwDataSize,4); 
    char *pData = new char[dwDataSize]; 
 
    file.read(pData,dwDataSize); 
    file.close(); 
    
  }
Вопрос: чем заменить MAKEFOURCC, WAVEFORMATEХ ?
Или это не поможет?
0
84 / 4 / 0
Регистрация: 01.02.2012
Сообщений: 93
25.06.2015, 20:23  [ТС]
Поменяла тип uint32 на uint16 - заголовок стал 44 байта, но в массив теперь пишуся нули(
Миниатюры
Считывание массива семплов из WAV  
0
 Аватар для iRomul
163 / 104 / 14
Регистрация: 17.10.2012
Сообщений: 488
25.06.2015, 20:28
омг, скиньте тот код, который конкретно в данный момент запускаете.
0
84 / 4 / 0
Регистрация: 01.02.2012
Сообщений: 93
25.06.2015, 21:02  [ТС]
vxg, Кстати, запустив ваш код получила как и у себя размер заголовка 52, а не 44

Добавлено через 1 минуту
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <math.h>
 
#include <stdint.h>
 
using namespace std;
 
struct  WAV_HEADER{
 
        /*char              chunkId[4];     // RIFF Header      Magic header
        unsigned long       chunkSize;      // RIFF Chunk Size
        char                format[4];      // WAVE Header
        char                subchunk1Id[4]; // FMT header
        unsigned long       subchunk1Size;  // Size of the fmt chunk
        unsigned short      audioFormat;    // Audio format 1=PCM,6=mulaw,7=alaw, 257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM
        unsigned short      numChannels;    // Number of channels 1=Mono 2=Sterio
        unsigned long       sampleRate;     // Sampling Frequency in Hz
        unsigned long       byteRate;       // bytes per second
        unsigned short      blockAlign;     // 2=16-bit mono, 4=16-bit stereo
        unsigned short      bitsPerSample;  // Number of bits per sample
        char                Subchunk2ID[4]; // "data"  string
        unsigned long       Subchunk2Size;  // Sampled data length
    */
 
    uint8_t       chunkId[4];     // RIFF Header
    uint32_t      chunkSize;      // RIFF Chunk Size
    uint8_t       format[4];      // WAVE Header
        uint8_t       subchunk1Id[4]; // FMT header
        uint32_t      subchunk1Size;  // Size of the fmt chunk
        uint16_t      audioFormat;    // Audio format 1=PCM
        uint32_t      numChannels;    // Number of channels 1=Mono 2=Sterio
        uint32_t      sampleRate;     // Sampling Frequency in Hz
        uint32_t      byteRate;       // bytes per second
        uint32_t      blockAlign;     // 2=16-bit mono, 4=16-bit stereo
        uint32_t      bitsPerSample;  // Number of bits per sample
        uint8_t       Subchunk2ID[4]; // "data"  string
        uint32_t      Subchunk2Size;  // Sampled data length
 
    //std::vector<long double> data;
    //std::vector<char*> data;     //ne pishet - segm_fault
 
    };
 
struct WAV_DATA{
 
    std::vector<long> data;
};
 
int main()
{
 
//printf("Long = %ld\n", sizeof(long)); //=8
//printf("Short = %ld\n", sizeof(short)); //=2
//printf("INT = %ld\n", sizeof(int)); //=4
//printf("DOUBLE = %ld\n", sizeof(double)); //=8
 
        WAV_HEADER wavHeader;
    WAV_DATA wavData;
        FILE *wavFile;
    int i=0;
 
    //wavHeader.data.reserve(255);
 
        long headerSize = sizeof(wavHeader), filelength = 0;
 
    /*
    char FilePath[16]; //simbol in namefile
    scanf("%s", FilePath);
    wavFile = fopen(FilePath, "rb");
    */
 
     wavFile = fopen ("pilotag_wav.wav", "rb");
 
     if (wavFile!=NULL)
      {
        cout << "File Open\n"; 
      } 
      else 
      {
         cout << "File no open\n"; 
      }
      
        fread(&wavHeader,headerSize,1,wavFile);
    unsigned long size = labs(wavHeader.Subchunk2Size); 
    printf("HeaderSize = %ld\n", headerSize);
    
        printf("Audio Format: %d\n", wavHeader.audioFormat);
        printf("Channels: %d\n", wavHeader.numChannels);
    printf("Sample rate (Hz): %d\n", wavHeader.sampleRate);
    printf("Byte per sec_play: %d\n", wavHeader.byteRate);
        printf("Byte per sample: %d\n", wavHeader.blockAlign);
    printf("Bits per sample: %d\n", wavHeader.bitsPerSample);
    
    
    printf("RIFF = %s\n", wavHeader.chunkId);
    printf("Format = %s\n", wavHeader.format);
    printf("FMT = %s\n", wavHeader.subchunk1Id);
    printf("DATA = %s\n", wavHeader.Subchunk2ID);
 
 
 
/// po primery
    int sample_size = wavHeader.bitsPerSample / 8;
    int samples_count = wavHeader.Subchunk2Size * 8 / wavHeader.bitsPerSample;
 
    int32_t *pData = new int32_t[samples_count]; 
 
    int32_t value = 0;
 
        for (int i = 0; i < samples_count; i++)
        {
            //unsigned long value = 0;
            fread(&value, sample_size, 1, wavFile);  
        pData[i]= value;
 
                //do something with value
        }
 
    /*for (int j=0; j<255; j++)
    {
        printf("pData%d = %d\n", j, pData[j]);
    }*/
 
 
 
 
 
    fclose(wavFile); 
      
    return 0;
}
Добавлено через 1 минуту
iRomul, Вот так получила 44 байта заголовка, но массив из 0

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <math.h>
 
#include <stdint.h>
 
using namespace std;
 
struct  WAV_HEADER{
 
        /*char              chunkId[4];     // RIFF Header      Magic header
        unsigned long       chunkSize;      // RIFF Chunk Size
        char                format[4];      // WAVE Header
        char                subchunk1Id[4]; // FMT header
        unsigned long       subchunk1Size;  // Size of the fmt chunk
        unsigned short      audioFormat;    // Audio format 1=PCM,6=mulaw,7=alaw, 257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM
        unsigned short      numChannels;    // Number of channels 1=Mono 2=Sterio
        unsigned long       sampleRate;     // Sampling Frequency in Hz
        unsigned long       byteRate;       // bytes per second
        unsigned short      blockAlign;     // 2=16-bit mono, 4=16-bit stereo
        unsigned short      bitsPerSample;  // Number of bits per sample
        char                Subchunk2ID[4]; // "data"  string
        unsigned long       Subchunk2Size;  // Sampled data length
    */
 
    uint8_t       chunkId[4];     // RIFF Header
    uint32_t      chunkSize;      // RIFF Chunk Size
    uint8_t       format[4];      // WAVE Header
        uint8_t       subchunk1Id[4]; // FMT header
        uint32_t      subchunk1Size;  // Size of the fmt chunk
        uint8_t      audioFormat;    // Audio format 1=PCM
        uint8_t      numChannels;    // Number of channels 1=Mono 2=Sterio
        uint32_t      sampleRate;     // Sampling Frequency in Hz
        uint32_t      byteRate;       // bytes per second
        uint8_t      blockAlign;     // 2=16-bit mono, 4=16-bit stereo
        uint8_t      bitsPerSample;  // Number of bits per sample
        uint8_t       Subchunk2ID[4]; // "data"  string
        uint32_t      Subchunk2Size;  // Sampled data length
 
    //std::vector<long double> data;
    //std::vector<char*> data;     //ne pishet - segm_fault
 
    };
 
struct WAV_DATA{
 
    std::vector<long> data;
};
 
int main()
{
 
//printf("Long = %ld\n", sizeof(long)); //=8
//printf("Short = %ld\n", sizeof(short)); //=2
//printf("INT = %ld\n", sizeof(int)); //=4
//printf("DOUBLE = %ld\n", sizeof(double)); //=8
 
        WAV_HEADER wavHeader;
    WAV_DATA wavData;
        FILE *wavFile;
    int i=0;
 
    //wavHeader.data.reserve(255);
 
        long headerSize = sizeof(wavHeader), filelength = 0;
 
    /*
    char FilePath[16]; //simbol in namefile
    scanf("%s", FilePath);
    wavFile = fopen(FilePath, "rb");
    */
 
     wavFile = fopen ("pilotag_wav.wav", "rb");
 
     if (wavFile!=NULL)
      {
        cout << "File Open\n"; 
      } 
      else 
      {
         cout << "File no open\n"; 
      }
      
        fread(&wavHeader,headerSize,1,wavFile);
    unsigned long size = labs(wavHeader.Subchunk2Size); 
    printf("HeaderSize = %ld\n", headerSize);
    
        printf("Audio Format: %d\n", wavHeader.audioFormat);
        printf("Channels: %d\n", wavHeader.numChannels);
    printf("Sample rate (Hz): %d\n", wavHeader.sampleRate);
    printf("Byte per sec_play: %d\n", wavHeader.byteRate);
        printf("Byte per sample: %d\n", wavHeader.blockAlign);
    printf("Bits per sample: %d\n", wavHeader.bitsPerSample);
    
    
    printf("RIFF = %s\n", wavHeader.chunkId);
    printf("Format = %s\n", wavHeader.format);
    printf("FMT = %s\n", wavHeader.subchunk1Id);
    printf("DATA = %s\n", wavHeader.Subchunk2ID);
 
 
 
/// po primery
    int sample_size = wavHeader.bitsPerSample / 8;
    int samples_count = wavHeader.Subchunk2Size * 8 / wavHeader.bitsPerSample;
 
    int32_t *pData = new int32_t[samples_count]; 
 
    int32_t value = 0;
 
        for (int i = 0; i < samples_count; i++)
        {
            //unsigned long value = 0;
            fread(&value, sample_size, 1, wavFile);  
        pData[i]= value;
 
                //do something with value
        }
 
    /*for (int j=0; j<255; j++)
    {
        printf("pData%d = %d\n", j, pData[j]);
    }*/
 
 
 
 
 
    fclose(wavFile); 
      
    return 0;
}
Добавлено через 26 минут
Я похоже поняла, что значат значения в массиве (значения от 0 до 255), но не понимаю, как привести их к виду матлаба.

Теперь, что касается амплитуды (громкости звука в коротком промежутке времени). От нее, я бы сказал, зависит точность звука. Амплитуда выражается числом, занимаемым в памяти (файле) 8, 16, 24, 32 бит (теоретически можно и больше). Как известно, 8 бит = 1 байту, следовательно, какая-то одна амплитуда в какой-то короткий промежуток времени в памяти (файле) может занимать 1, 2, 3, 4 байта соответственно. Таким образом, чем больше число занимает места в памяти (файле), тем больше диапазон значений для этого числа, а значит и для амплитуды.

1 байт – 0..255
2 байта – 0..65 535
3 байта – 0..16 777 216
4 байта – 0..4 294 967 296
В моно варианте значения амплитуды расположены последовательно.
0
84 / 4 / 0
Регистрация: 01.02.2012
Сообщений: 93
25.06.2015, 22:21  [ТС]
iRomul,

Разобралась с 44 байтами. Но похоже в заголовке перед DATA еще идут поля LIST и INFO с INAM. Пытаюсь пропустить их но никак не могу попасть на DATA. В массив начал писаться какие-то значения.
Миниатюры
Считывание массива семплов из WAV  
0
84 / 4 / 0
Регистрация: 01.02.2012
Сообщений: 93
26.06.2015, 00:13  [ТС]
Дошла до чанка с data. Записывается массив значений в виде "числа, занимаемым в памяти бит" в пределах 2 бит.
Как можно получить амплитуды, которые дает матлаб, если здесь 65 000 а надо в пределах +-1?
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,476
26.06.2015, 10:17
Цитата Сообщение от Trisha Ray Посмотреть сообщение
Кстати, запустив ваш код получила как и у себя размер заголовка 52, а не 44
если вы не заменили DWORD на uint32_t то размер будет хз какой
Цитата Сообщение от Trisha Ray Посмотреть сообщение
Как можно получить амплитуды
как минимум попробуйте следующее:
1 - отнимите от всех значений (2^16 - 1) / 2, приведите к float и поделите на 2^16
2 - найдите мин и макс значение, отнимите от всех значений мин + (макс + мин) / 2, приведите к float и поделите на (макс - мин)
0
84 / 4 / 0
Регистрация: 01.02.2012
Сообщений: 93
27.06.2015, 11:25  [ТС]
1) не помогло впринципе (пробовала и для инта 2^31-2 так как тип массива указала int32_t)

2) нормировало примерно к одному десятичному числу, а матлаб показывает совсем другое

-0,00137329101562500
-0,00244140625000000
-0,00198364257812500
-0,00140380859375000
-0,00186157226562500
-0,00250244140625000
-0,00256347656250000
-0,00198364257812500
-0,00122070312500000
-0,00189208984375000
-0,00167846679687500
-0,00198364257812500
-0,00186157226562500
-0,00140380859375000
-0,00125122070312500
-0,00137329101562500
-0,000549316406250000

Может надо преобразовывать с помощью частоты?
" Звук состоит из колебаний, которые при оцифровке приобретают ступенчатый вид. Этот вид обусловлен тем, что компьютер может воспроизводить в любой короткий промежуток времени звук определенной амплитуды (громкости) и этот короткий момент далеко не бесконечно короткий. Продолжительность этого промежутка и определяет частота дискретизации. Например, у нас файл с частотой дискретизации 44.1 kHz, это значит, что тот короткий промежуток времени равен 1/44100 секунды (следует из размерности величины Гц = 1/с). Современные звуковые карты поддерживают частоту дискретизации до 192 kHz. Так, со временем разобрались.

Теперь, что касается амплитуды (громкости звука в коротком промежутке времени). От нее, я бы сказал, зависит точность звука. Амплитуда выражается числом, занимаемым в памяти (файле) 8, 16, 24, 32 бит (теоретически можно и больше). Как известно, 8 бит = 1 байту, следовательно, какая-то одна амплитуда в какой-то короткий промежуток времени в памяти (файле) может занимать 1, 2, 3, 4 байта соответственно. Таким образом, чем больше число занимает места в памяти (файле), тем больше диапазон значений для этого числа, а значит и для амплитуды.

1 байт – 0..255
2 байта – 0..65 535"
0
84 / 4 / 0
Регистрация: 01.02.2012
Сообщений: 93
27.06.2015, 12:11  [ТС]
Эти варианты не помогли
Миниатюры
Считывание массива семплов из WAV  
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,476
29.06.2015, 13:55
Цитата Сообщение от Trisha Ray Посмотреть сообщение
не помогло впринципе
)
не могли бы вы выложить тестовый файл и ту последовательность которую дает матлаб для этого файла
0
84 / 4 / 0
Регистрация: 01.02.2012
Сообщений: 93
29.06.2015, 16:13  [ТС]
vxg, результаты и матлаб файл
Вложения
Тип файла: rar matlab.rar (40.1 Кб, 19 просмотров)
0
84 / 4 / 0
Регистрация: 01.02.2012
Сообщений: 93
29.06.2015, 16:31  [ТС]
vxg, wav файл

Добавлено через 17 минут
Нашла пример, но такое деление тоже не дает результата. + еще не подключается сторонняя библиотека

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
/* -------- C++ Sound Library for Signal Processing --------
This library needs Eigen.
[url]http://eigen.tuxfamily.org/index.php?title=Main_Page[/url]
 
Copyright (c) Hayato OHYA 2013 All Rights Reserved.
E-mail : [email]hayato@mlab.phys.waseda.ac.jp[/email]
 
reference
[1] Naofumi AOKI, CЊѕЊк‚Е‚Н‚¶‚߂鉹‚МѓvѓЌѓOѓ‰ѓ~ѓ“ѓO, 2008 (in Japanese)
[2] [url]http://d.hatena.ne.jp/yatt/20090904/1252078381[/url] (in Japanese)
[3] [url]http://www.kk.iij4u.or.jp/~kondo/wave/[/url] (in Japanese)
[4] [url]http://d.hatena.ne.jp/uppudding/20071223/1198420222[/url] (in Japanese)
--------------------------------------------------------------*/
#include <string>
#include <string.h>
#include <Eigen/Core>
#include <iostream>
using namespace std;
 
namespace sl
{
    // struct -----------------------------------------------------
    struct Wav // basic WAVE file structure
    {
        int fs; // Samples per Second
        int bits; //  Bits per Sample
        int channel; // Sound Data Channels
        int length; // Sound Data Length
        Eigen::MatrixXd data;
    };
 
    struct Fft // structure for FFT
    {
        Eigen::VectorXd real; // real part of fft
        Eigen::VectorXd imag; // imaginary part of fft
    };
 
    struct Spec // structure for spectrogram
    {
        int fs; // Samples per Second
        int fftPoints; // Points  of FFT
        Eigen::MatrixXd data; // spectrogram data (row : time, col : frequency)
    };
 
    // function --------------------------------------------------
    Wav wavread(string wavPath);
    void wavwrite(string wavPath, Wav wavData);
    Wav stereo2mono(Wav wavData);
    Wav mono2stereo(Wav wavData, double delayTime = 0.005);
    void showWavData(Wav wavData);
    Wav convertSamplingRate(Wav wavData, int fs); // incomplete
    Eigen::MatrixXd iPow(Eigen::MatrixXd, Eigen::MatrixXd);
    double sinc(double);
 
    Wav wavread(string wavPath)
    {
        /*MATLAB like wavread function*/
        // input : WAVE file absolute path
        // output : Wav struct data defined above
        const char *wavPath_c = wavPath.c_str();
        Wav output;
 
        FILE *fp;
        errno_t error;
        int n, m;
 
        char riff_chunkID[4];
        long riff_chunkSize;
        char riff_formType[4];
        char fmt_chunkID[4];
        long fmt_chunkSize;
        short fmt_waveFormatType;
        short fmt_channel;
        long fmt_samplesPerSec;
        long fmt_bytesPerSec;
        short fmt_blockSize;
        short fmt_bitsPerSample;
        char data_chunkID[4];
        long data_chunkSize;
        short data;
 
        long fmt_extend;
        char find_data_char[2]; // To find "data"
        char find_data_char_old[2]; // To find "data"
        int dataBlockSize; // data size per sample
 
        if (error = fopen_s(&fp, wavPath_c, "rb") != 0){
            cout << "ERROR : Cannot read wave file. Check file path." << endl;
            output.bits = -1;
            output.channel = -1;
            output.data = Eigen::MatrixXd::Zero(1,1);
            output.fs = -1;
            output.length = -1;
            return output;
        }
 
        // RIFF
        fread(riff_chunkID, 1, 4, fp);
        fread(&riff_chunkSize, 4, 1, fp);
        fread(riff_formType, 1, 4, fp);
 
        // fmt chunk
        fread(fmt_chunkID, 1, 4, fp);
        fread(&fmt_chunkSize, 4, 1, fp); // Linear PCM = 16
        fread(&fmt_waveFormatType, 2, 1, fp);
        fread(&fmt_channel, 2, 1, fp);
        fread(&fmt_samplesPerSec, 4, 1, fp);
        fread(&fmt_bytesPerSec, 4, 1, fp);
        fread(&fmt_blockSize, 2, 1, fp);
        fread(&fmt_bitsPerSample, 2, 1, fp);
        if (fmt_chunkSize != 16){ // if WAVE file is not linear PCM
            cout << "WARNING : This file is not linear PCM" << endl;
            cout << "There is a possibility to be malfunctioning." << endl;
            fread(&fmt_extend, fmt_chunkSize -16, 1, fp);
        }
 
        // data chunk
        fread(data_chunkID, 1, 4, fp);
        if (memcmp(data_chunkID,"data", sizeof(data_chunkID))!=0){// find "data" in the binary data
            fread(find_data_char_old, 1, 2, fp);
            while (1){
                fread(find_data_char, 1, 2, fp);
                if (memcmp(find_data_char_old,"da", sizeof(find_data_char_old))==0 && memcmp(find_data_char,"ta", sizeof(find_data_char))==0) // find "data"
                    break;
                find_data_char_old[0] = find_data_char[0];
                find_data_char_old[1] = find_data_char[1];
            }
        }
        fread(&data_chunkSize, 4, 1, fp);
 
        output.fs = fmt_samplesPerSec;
        output.bits = fmt_bitsPerSample;
        output.length = data_chunkSize / (fmt_bitsPerSample / 8) / fmt_channel;
        output.channel = fmt_channel;
        output.data = Eigen::MatrixXd::Zero(output.length, output.channel);
 
        // read wave data
        dataBlockSize = fmt_blockSize / fmt_channel;
        if (fmt_channel == 1){
            for (n = 0; n < output.length; n++){
                fread(&data, dataBlockSize, 1, fp);
                output.data(n,0) = (double) data / 32768.0; // normalize in range from -1 to 1
            }
        }else if(fmt_channel == 2){
            for (n = 0; n < output.length; n++){
                for (m=0; m<2; m++){
                    fread(&data, dataBlockSize, 1, fp);
                    output.data(n,m) = (double) data / 32768.0; // normalize in range from -1 to 1
                }
            }
        }
 
        fclose(fp);
        return output;
    }
 
    void wavwrite(string wavPath, Wav wavData)
    {
        /*Write WAVE file with linear PCM, 16bit*/
        // argument 1 : wave file path
        // argument 2 : wave file data
        const char *wavPath_c = wavPath.c_str();
        FILE *fp;
        errno_t error;
        int n, m;
 
        char riff_chunkID[4];
        long riff_chunkSize;
        char riff_formType[4];
        char fmt_chunkID[4];
        long fmt_chunkSize;
        short fmt_waveFormatType;
        short fmt_channel;
        long fmt_samplesPerSec;
        long fmt_bytesPerSec;
        short fmt_blockSize;
        short fmt_bitsPerSample;
        char data_chunkID[4];
        long data_chunkSize;
        short data;
        Eigen::MatrixXd mat = Eigen::MatrixXd::Ones(wavData.data.rows(), wavData.data.cols());
        int dataBlockSize;
 
        riff_chunkID[0] = 'R';
        riff_chunkID[1] = 'I';
        riff_chunkID[2] = 'F';
        riff_chunkID[3] = 'F';
        riff_chunkSize = 36 + wavData.length * wavData.bits/8 * wavData.channel;
        riff_formType[0] = 'W';
        riff_formType[1] = 'A';
        riff_formType[2] = 'V';
        riff_formType[3] = 'E';
 
        fmt_chunkID[0] = 'f';
        fmt_chunkID[1] = 'm';
        fmt_chunkID[2] = 't';
        fmt_chunkID[3] = ' ';
        fmt_chunkSize = 16; // linear PCA : 16
        fmt_waveFormatType = 1;
        fmt_channel = wavData.channel;
        fmt_samplesPerSec = wavData.fs;
        fmt_bytesPerSec = wavData.fs * wavData.bits/8 * wavData.channel;
        fmt_blockSize = wavData.bits/8 * wavData.channel;
        fmt_bitsPerSample = wavData.bits;
 
        data_chunkID[0] = 'd';
        data_chunkID[1] = 'a';
        data_chunkID[2] = 't';
        data_chunkID[3] = 'a';
        data_chunkSize = wavData.length * wavData.bits/8 * wavData.channel;
 
        if (error = fopen_s(&fp, wavPath_c, "wb") != 0){
            cout << "ERROR : Cannot open " << wavPath << endl;
            return;
        }
 
        // RIFF
        fwrite(riff_chunkID, 1, 4, fp);
        fwrite(&riff_chunkSize, 4, 1, fp);
        fwrite(riff_formType, 1, 4, fp);
 
        // fmt chunk
        fwrite(fmt_chunkID, 1, 4, fp);
        fwrite(&fmt_chunkSize, 4, 1, fp); // Linear PCM = 16
        fwrite(&fmt_waveFormatType, 2, 1, fp);
        fwrite(&fmt_channel, 2, 1, fp);
        fwrite(&fmt_samplesPerSec, 4, 1, fp);
        fwrite(&fmt_bytesPerSec, 4, 1, fp);
        fwrite(&fmt_blockSize, 2, 1, fp);
        fwrite(&fmt_bitsPerSample, 2, 1, fp);
 
        // data chunk
        fwrite(data_chunkID, 1, 4, fp);
        fwrite(&data_chunkSize, 4, 1, fp);
 
        dataBlockSize = fmt_blockSize / fmt_channel;
        mat = (mat + wavData.data) / 2.0 * 65536;
        if (fmt_channel == 1){
            for (n=0; n< wavData.length; n++){
                if (mat(n,0)> 65535.0){
                    mat(n,0) = 65535.0; // clipping
                }else if (mat(n,0) < 0){
                    mat(n,0) = 0.0; // clipping
                }
                data = (short) (mat(n,0) + 0.5) -32768; // round off and adjust off-set
                fwrite(&data, dataBlockSize, 1, fp);
            }
        }else if(fmt_channel == 2){
            for (n=0; n< wavData.length; n++){
                for (m=0; m<2; m++){
                    if (mat(n,m)> 65535.0){
                        mat(n,m) = 65535.0; // clipping
                    }else if (mat(n,m) < 0){
                        mat(n,m) = 0.0; // clipping
                    }
                    data = (short) (mat(n,m) + 0.5) -32768; // round off and adjust off-set
                    fwrite(&data, dataBlockSize, 1, fp);
                }
            }
        }
 
        fclose(fp);
    }
 
    Wav stereo2mono(Wav wavData)
    {
        /*Convert WAVE data from stereo into monaural signal*/
        Wav output;
        if (wavData.channel != 2){
            cout << "ERROR : The number of channels must be 2." << endl;
            return wavData;
        }
        output.bits = wavData.bits;
        output.channel = 1;
        output.fs = wavData.fs;
        output.length = wavData.length;
        output.data = (wavData.data.col(0) + wavData.data.col(1)) / 2.0;
        return output;
    }
 
    Wav mono2stereo(Wav wavData, double delayTime)
    {
        /*Convert WAVE data from monaural signal into stereo*/
        // quasi-stereo
 
        Wav output;
        Eigen::MatrixXd mat;
        int tempTime;
        if (wavData.channel != 1){
            cout << "ERROR : The number of channels must be 1." << endl;
            return output;
        }
        output.bits = wavData.bits;
        output.channel = 2;
        output.fs = wavData.fs;
        output.length = wavData.length;
        mat = Eigen::MatrixXd::Zero(wavData.length, 2);
        mat.col(0) = wavData.data.col(0);
        mat.col(1) = wavData.data.col(0);
 
        delayTime *= wavData.fs;
 
        for (int i=0; i<wavData.length; i++){
            tempTime = i - (int) delayTime;
            if (tempTime >= 0){
                mat(i,0) += wavData.data(tempTime,0);
                mat(i,0) -= wavData.data(tempTime,0);
            }
        }
        output.data = mat;
        return output;
    }
 
    void showWavData(Wav wavData)
    {
        /*Print WAVE file data*/
        cout << "Bits : " << wavData.bits << endl;
        cout << "Channel : " << wavData.channel << endl;
        cout << "Sampling rate : " << wavData.fs << endl;
        cout << "Data length : " << wavData.length << endl;
    }
 
    Wav convertSamplingRate(Wav wavData, int fs)
    {
        Wav output;
        float counter, sumCount;
        int i, n;
        Eigen::MatrixXd outputData;
 
        if (wavData.fs > fs){ // down sampling
            counter = (float) fs / wavData.fs;
            sumCount = 0;
 
            int newLength = (int) floor(counter * wavData.length);
            outputData = Eigen::MatrixXd::Zero(newLength, wavData.channel); // initialization
            n = 0;
 
            // down sampling
            if (wavData.channel == 1){
                for (i=0; i<wavData.length; i++){
                    if (sumCount >= 1.0){
                        outputData(n,0) = wavData.data(i,0);
                        sumCount = sumCount - 1;
                        n++;
                    }
                    sumCount = sumCount + counter;
                }
            }else if (wavData.channel == 2){
                for (i=0; i<wavData.length; i++){
                    if (sumCount >= 1.0){
                        outputData(n,0) = wavData.data(i,0);
                        outputData(n,1) = wavData.data(i,1);
                        sumCount = sumCount - 1;
                        n++;
                    }
                    sumCount = sumCount + counter;
                }
            }
            // assignment
            output.bits = wavData.bits;
            output.channel = wavData.channel;
            output.length = newLength;
            output.fs = fs;
            output.data = outputData;
        }else if (wavData.fs < fs){ // up sampling
 
        }else{
            cout << "WARNING : WAVE data cannot be converted." << endl;
            output = wavData;
        }
        return output;
    }
 
    Eigen::VectorXd iPow(Eigen::VectorXd x_real, Eigen::VectorXd x_imag)
    {
        Eigen::VectorXd output;
        output = x_real.cwiseProduct(x_real) + x_imag.cwiseProduct(x_imag);
        return output;
    }
 
    int log2(int num)
    {
        if (num<0){
            return -1;
        }
        return log(num) / log(2);
    }
 
    double sinc(double x)
    {
        double y;
        if(x == 0.0){
            y = 1.0;
        }else{
            y = sin(x) / x;
        }
        return y;
    }
 
}
0
84 / 4 / 0
Регистрация: 01.02.2012
Сообщений: 93
29.06.2015, 16:46  [ТС]
vxg,
Вложения
Тип файла: rar 1.rar (17.5 Кб, 20 просмотров)
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,476
01.07.2015, 13:27
Цитата Сообщение от Trisha Ray Посмотреть сообщение
не дает результата
итак, опытным путем выяснено, что в matlab функция wavread преобразует значения следующим образом:
-берем "нормальное значение" (0..0xFFFF)
-преобразуем его к типу double
-отнимаем 0x8000 - то есть теперь наш ноль будет в центре диапазона (внизу будет 0x8000 штук отрицательных значений, вверху будет 0x8000 штук положительных значений, причем нулевые значения считаются положительными) - то есть теперь мы будем иметь значения в диапазоне [-0x8000, 0x8000) или, что тоже самое [-0x8000, 0x7FFF]
-делим на 0x8000 - то есть теперь мы будем иметь значения в диапазоне [-1, +1)
-А ТЕПЕРЬ РОК-Н-РОЛЛ - полученное значение matlab преобразует очень странным методом. каким именно мне неизвестно, но результат работы такой же как если бы мы сделали следующее: если значение больше нуля, то результат будет равен значение минус один, если значение меньше нуля, то результат будет равен значение плюс один. как будто мы берем не амплитуду, а значение которое нужно добавить к амплитуде что бы она стала равной единице. зачем? вообще не знаю. можете написать разработчикам matlab. беглый поиск вообще говорит, что значения должны быть нормированы к диапазону [-1, +1). кроме того по этой же ссылке мы видим, что значения могут быть загружены в "нормальном" виде (0..0xFFFF) если использовать выражение вида
Matlab M
1
[Y,Fs,bits]=wavread('C:\\1.wav', 'native');
не знаю - не пробовал.
вот собственно код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <windows.h>
#include <stdio.h>
#include <math.h>
 
//sizeof(WORD) = 16 bits = 2 bytes
//sizeof(DWORD) = 32 bits = 4 bytes
 
struct wav_header_t
{
    char rId[4]; //"RIFF" = 0x46464952
    DWORD rLen; //28 [+ sizeof(wExtraFormatBytes) + wExtraFormatBytes] + sum(sizeof(chunk.id) + sizeof(chunk.size) + chunk.size)
    char wId[4]; //"WAVE" = 0x45564157
    char fId[4]; //"fmt " = 0x20746D66
    DWORD fLen; //16 [+ sizeof(wExtraFormatBytes) + wExtraFormatBytes]
    WORD wFormatTag;
    WORD nChannels;
    DWORD nSamplesPerSec;
    DWORD nAvgBytesPerSec;
    WORD nBlockAlign;
    WORD wBitsPerSample;
    //[WORD wExtraFormatBytes;]
    //[Extra format bytes]
};
 
struct chunk_t
{
    char id[4]; //"data" = 0x61746164
    DWORD size;
    //Chunk data bytes
};
 
int main(void)
{
    FILE *f = fopen("test.wav", "rb");
 
    wav_header_t header;
 
    fread(&header, sizeof(header), 1, f);
 
    printf("wFormatTag=%i\n", header.wFormatTag);
    printf("nChannels=%i\n", header.nChannels);
    printf("nSamplesPerSec=%li\n", header.nSamplesPerSec);
    printf("wBitsPerSample=%i\n", header.wBitsPerSample);
 
    fseek(f, header.fLen - 16, SEEK_CUR); //skip wExtraFormatBytes & extra format bytes
 
    chunk_t chunk;
    printf("id\t" "size\n");
    while (true) //go to data chunk
    {
        fread(&chunk, sizeof(chunk), 1, f);
        printf("%c%c%c%c\t" "%li\n", chunk.id[0], chunk.id[1], chunk.id[2], chunk.id[3], chunk.size);
        if (*(DWORD *)&chunk.id == 0x61746164) break;
        fseek(f, chunk.size, SEEK_CUR); //skip chunk data bytes
    }
 
    int sample_size = header.wBitsPerSample / 8;
    int samples_count = chunk.size * 8 / header.wBitsPerSample;
 
    printf("samples_count=%i\n", samples_count);
 
    DWORD *value = new DWORD[samples_count];
    memset(value, 0, sizeof(DWORD) * samples_count);
 
    for (int i = 0; i < samples_count; i++)
    {
        fread(&value[i], sample_size, 1, f);
    }
 
    fclose(f);
 
    f = fopen("test.dat", "w");
    fprintf(f, "value (0..0xFFFF)\t" "value (-1..1)\t" "value (matlab)\n");
    for (int i = 0; i < samples_count; i++)
    {
        //for 16 bits per sample only
        double x = ((double)value[i]- 0x8000) / 0x8000;
        double y = x > 0.0? x - 1.0 : x + 1.0;
        fprintf(f, "%lu\t" "%1.17lf\t" "%1.17lf\n", value[i], x, y);
    }
    fclose(f);
 
    system("pause");
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
01.07.2015, 13:27

Считывание больших wav файлов частями
Привет ребята, столкнулся со следующей проблемой, у меня есть wav файл размером 2Gb, мне его нужно проанализировать, я понимаю что...

Запись и считывание информации в WAV-файл
Всем добрый день. Занимаюсь такой проблемой: необходимо записать в звуковой файл и считать из него определенную последовательность. При...

Нужна помощь в заказе семплов(Coilcraft). Оплата.
Добрый день уважаемые форумчане! Решил собрать терменвокс по схеме Роберта Муга (гуглить Etherwave Theremin) но появилась проблема -...

Написать программу, формирующую по исходному WAV файлу новый WAV файл
Написать программу, формирующую по исходному WAV файлу новый WAV файл, со сглаженным вершинами перегруженных (клипированных) фрагментов....

Применить фильтр который будет брать первые 5 семплов, считать среднее и записывать в другой массив
Есть массив звука (например 1024 штуки). Есть параметр ширины окна (например 5 семплов). Нужно применить фильтр который будет брать...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Книги по геймдизайну, левел-дизайну, игровым механикам и проектированию игрового опыта
8Observer8 08.11.2026
Содержание блога | English Version 1. 2003 - 06 - Designing Virtual Worlds (1st Edition) Автор: Richard A. Bartle | Объем: 768 стр. Ссылки: Amazon . . .
Родители токсичные абьюзеры по отношению к своим детям ругают их оскорбляют не любят
zorxor 08.11.2026
Жить в атмосфере постоянных оскорблений, критики и холодности со стороны родителей — это тяжелое и болезненное испытание, которое оставляет глубокие эмоциональные раны. Токсичное и абьюзивное. . .
Как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Ответ от Джемени ИИ.
zorxor 08.11.2026
Джемени, как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Многие люди, возвращаясь домой, сразу переодеваются в максимально свободную одежду или вовсе предпочитают. . .
Паттерн очереди действий/команд (Action / Command Queue). Система очереди действий и кат-сцен с SDL3 Callbacks, cglm и OpenGL
8Observer8 07.11.2026
Содержание блога | English Version Руководство для начинающих по реализации паттерна очереди действий/ команд (Action / Command Queue) на C++ (C++20) с использованием официального SDL3 Callbacks. . .
Проверка полного ФИО в типовом справочнике
Maks 07.11.2026
Решение реализовано в конфигурации КА2, на примере справочника "КонтактныеЛицаПартнеров". Задача: Запрет инициалов. Не допускаеть использование сокращений вида "И. И. ", "И. И. ", "И И" и. . .
Про "Windows must die!"
kumehtar 04.11.2026
Знаете, чет накатило. . . . Когда-то это было почти боевым кличем: мол, нормальный человек сидит на DOS, OS/ 2 или Linux, а вот это вот - Must Die. А теперь человек произносит «мастдай» с усмешкой - и. . .
Красочные поля с номером страницы svg+background-image
russiannick 04.11.2026
Красочные поля с номером страницы не менее важны чем в эпоху бумажных книг. Посему спешу представить почтеннейшей публике этот важный инструмент который эти поля и формирует. В процессе разработки. . .
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru