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

Нет звука в выходном .wav файле при записи

07.03.2022, 18:24. Показов 875. Ответов 7

Студворк — интернет-сервис помощи студентам
Я пишу библиотеку аудиоэффектов. Нужно считать .wav файл, прогнать его через алгоритмы эффектов, а потом записать обратно. Пока что застрял на чтении/записи. Проблема заключается в том, что выходной .wav файл имеет тот же размер, что и входной, ту же продолжительность трека. Однако, при воспроизведении звук отсутствует. Где я мог ошибиться в коде?

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
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
 
struct WavHeader
{
    char                chunkId[4];     // RIFF, FMT, DATA, e.t.c.
    unsigned long       ChunkSize;      // Chunk Size  
};
 
struct RiffHeader : WavHeader
{
    char                format[4];      // WAVE Header      
};
 
struct FmtHeader : WavHeader
{                            
    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
};
 
struct DataHeader : WavHeader
{
};
 
struct Wav
{
    RiffHeader RiffHeader;
    FmtHeader FmtHeader;
    DataHeader DataHeader;
    vector<char> Data;
};
 
/// <summary>
/// Read/write .wav files.
/// </summary>
class WavFileManager
{
public:
    /// <summary>
    /// Read whole .wav file.
    /// </summary>
    /// <param name="path">Path to file.</param>
    Wav ReadAll(const string& path)
    {
        ifstream file(path);
 
        if (!file)
        {
            throw runtime_error("Can't open file: " + path);
        }
 
        Wav* wavFile = new Wav();
 
        wavFile->RiffHeader = ReadHeader<RiffHeader>(file);
 
        if (wavFile->RiffHeader.format != "WAVE\0")
        {
            // throw runtime_error("Wrong format. File: " + path);
        }
 
        wavFile->FmtHeader = ReadHeader<FmtHeader>(file);
 
        if (!TrySkipChunksBefore(file, "data"))
        {
            throw runtime_error("Can't find wav data. File: " + path);
        }
 
        wavFile->DataHeader = ReadHeader<DataHeader>(file);
 
 
        vector<char>& data = wavFile->Data;
        data.reserve(wavFile->DataHeader.ChunkSize);
        for (int i = 0; i < wavFile->DataHeader.ChunkSize; i++)
        {
            char buffer;
            file.read((char*)&buffer, sizeof(char));
            data.push_back(buffer);
        }
        reverse(data.begin(), data.end());
 
 
        file.close();
        return *wavFile;
    }
 
    /// <summary>
    /// Read header of .wav file.
    /// </summary>
    /// <param name="file">File stream.</param>
    /// <returns>Header of type T.</returns>
    template<typename T>
    T ReadHeader(ifstream& file)
    {
        T header;
        int headerSize = sizeof(T);
        file.read((char*)&header, headerSize);
        return header;
    }
 
    /// <summary>
    /// Read data chunk of .wav file.
    /// </summary>
    /// <param name="file">File stream.</param>
    /// <param name="size">Chunk size.</param>
    /// <returns>Array of bytes.</returns>
    char* ReadChunk(ifstream& file, unsigned long size)
    {
        char* chunk = new char[size];
        file.read(chunk, size);
        return chunk;
    }
 
    /// <summary>
    /// Check if .wav header has following chunkId.
    /// </summary>
    /// <param name="header">.wav header.</param>
    /// <param name="chunkId">Id to compare.</param>
    bool HasChunkID(const WavHeader& header, const char chunkId[4])
    {
        return ((header.chunkId[0] == chunkId[0]) &&
            (header.chunkId[1] == chunkId[1]) &&
            (header.chunkId[2] == chunkId[2]) &&
            (header.chunkId[3] == chunkId[3]));
    }
 
    /// <summary>
    /// Skip all chunks before reqired chunk.
    /// </summary>
    /// <param name="file">File stream.</param>
    /// <param name="chunkId">Id of required chunk.</param>
    bool TrySkipChunksBefore(ifstream& file, const char chunkId[4])
    {
        while (!file.eof())
        {
            streampos pos = file.tellg();
            WavHeader header = ReadHeader<WavHeader>(file);
            char* chunk = ReadChunk(file, header.ChunkSize);
            if (HasChunkID(header, chunkId))
            {
                file.clear();
                file.seekg(pos);
                return true;
            }
            delete[] chunk;
        }
        return false;
    }
 
    /// <summary>
    /// Write all data into file.
    /// </summary>
    /// <param name="data">Wav to write.</param>
    /// <param name="path">Path to output file.</param>
    void WriteAll(Wav data, const string& path)
    {
        ofstream file(path, ios::binary);
        file.write((char*)&data.RiffHeader, sizeof(RiffHeader));
        file.write((char*)&data.FmtHeader, sizeof(FmtHeader));
        file.write((char*)&data.DataHeader, sizeof(DataHeader));
        reverse(data.Data.begin(), data.Data.end());
        for (int i = 0; i < data.Data.size(); i++)
        {
            file.write((char*)&data.Data[i], sizeof(char));
        }
        file.close();
    }
};
 
int main()
try
{
    auto* mgr = new WavFileManager();
    auto wav = mgr->ReadAll ("input.wav");
    mgr->WriteAll(wav, "output.wav");
}
catch (runtime_error& e)
{
    cerr << "Error! " << e.what() << '\n';
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.03.2022, 18:24
Ответы с готовыми решениями:

нет информации в выходном файле
Здравствуйте.По заданию (Дан массив размера N. Определить количество его промежутков монотонности (то есть участков, на которых его...

При записи звука windows sound recorder не совпадает число данных в хедере wav-файла с реальным значением?
При записи с микрофона стандартной windows прогой почему не совпадает число данных в хедере wav файла с реальным значением? Например,...

Нет звука в Sony Vegas при записи видео в OBS
Всем привет! Сразу извиняюсь если не в тот раздел пишу, или вообще не на том форуме. Но есть такая проблема. Не могу понять что не так...

7
Заблокирован
07.03.2022, 19:38
Цитата Сообщение от beton_kun Посмотреть сообщение
reverse(data.begin(), data.end());
Это зачем ?
0
0 / 0 / 0
Регистрация: 29.06.2018
Сообщений: 24
07.03.2022, 19:42  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
Это зачем ?
Чанк с данными в little-endian
0
 Аватар для Наталья8
518 / 368 / 65
Регистрация: 09.03.2016
Сообщений: 3,877
07.03.2022, 22:17
Если данные сдвинуты на байт вниз. то слышно ничего не будет.
Hex редактор подкати.
0
 Аватар для Наталья8
518 / 368 / 65
Регистрация: 09.03.2016
Сообщений: 3,877
07.03.2022, 22:23
Я когда то в этом ковырялся.
https://www.cyberforum.ru/atta... 1646680994
Миниатюры
Нет звука в выходном .wav файле при записи  
0
 Аватар для Наталья8
518 / 368 / 65
Регистрация: 09.03.2016
Сообщений: 3,877
07.03.2022, 22:36
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
//------------------------     
fseek(fp_in, (cur_next * byte_block) - crutch// КОРРЕКЦИЯ ======= ПРИБАВИТЬ ДВА (НЕ КОМПИЛИРУЕТ) ИЛИ ОТНЯТЬ
                , SEEK_SET);//<--- указатель положения в файле fseek ( ======= Правильно читать данные из входного файла ======= )
        //------------------------        
        _int8 buffer[8]; unsigned int nBuff = 0;
        while (fread(buffer, 1, byte_block, fp_in) == byte_block && nBuff < size_next){
                        
            if (header.audioFormat == 3){// Тридцатьдва бита
                //===========================   Пытаюсь регулировать звук float... (нижний блок short) 
                float *one = (float*)buffer;
                float sample[2];
                sample[0] = *one; one++; sample[1] = *one;
                sample[0] *= audio_set;
                sample[1] *= audio_set;
                //--------------------------
                _int8 *two = (_int8*)sample;
                for (int i = 0; i < 8; i++){ buffer[i] = *two; two++; }
 
                //===========================       
            } else if (byte_block == 4){// Шестнадцать бит
                short *one = (short*)buffer;
                short sample[2];
                sample[0] = *one; one++; sample[1] = *one;
                sample[0] *= audio_set;
                sample[1] *= audio_set;
                //--------------------------
                _int8 *two = (_int8*)sample;
                for (int i = 0; i < 4; i++){ buffer[i] = *two; two++; }
            }
  
 fwrite(buffer, 1, byte_block, fp_out);//<======== гоним данные в файл пока не конец файла, или кончиться фрагмент
            ++nBuff;
           }
      counter += nBuff;// Сбор общего размера... Т.Е. реально записанных восьмибайтных семплов (или четырёхбайтных при моно)
        ++indx;
        }
      else {
          Sleep(5);
            // Beep(3000,10);
            if (file_end) break; } //  очередь дописана(Сброс работы потока...из основной программы)
           }
//==========================================================================================    
    } else {
        
        header.chunkSize = WAVHEADER_SIZE - 8 +
            sizeof(WAV_FACT_CHUNK)+sizeof(WAV_DATA_CHUNK)+counter * byte_block;
      
header.subchunk2Size = counter * byte_block;// <<<======== header.blockAlign (с этой  уйни размер читаеться) это я изменил по новому
                        
        //-------------------- Запись шапки ----- Иб чие структуры не пишу -----------------------------------
        fseek(fp_out, 0, SEEK_SET);// SEEK_SET ---указатель положения в файле в начало файла
        size_t res = fwrite(&header, WAVHEADER_SIZE, 1, fp_out); //<------------писать WAVHEADER
        if (res<1)printf("data fwrite error!\n");
        fclose(fp_out); fclose(fp_in);
        std::cout << " --- close treadAudio--- " << std::endl;
    }
    return 0;
}
Добавлено через 36 секунд
Я у вас тоже ничего не понимаю

Добавлено через 1 минуту
Я просто прибавлял два. чего два не помню.
0
0 / 0 / 0
Регистрация: 29.06.2018
Сообщений: 24
09.03.2022, 12:28  [ТС]
Проблема решилась очень просто
C++
1
ifstream file(path);
заменил на
C++
1
ifstream file(path, ios::binary);
0
 Аватар для Наталья8
518 / 368 / 65
Регистрация: 09.03.2016
Сообщений: 3,877
09.03.2022, 23:50
Тоже бывает.
У меня данные начинались с середины семпла.
Тридцатидвухбитный float pcm.
или
Местами шестнадцатибитный SAMPLE_FMT_S16.

Добавлено через 10 минут
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
//формирование заголовков WAV-файла
    WAVHEADER header={
        {'R','I','F','F'},0,
        {'W','A','V','E'},{'f','m','t',' '},18,0,0,0,0,0,0,0
    };
 
header.chunkSize = WAVHEADER_SIZE - 8 +
         sizeof(WAV_FACT_CHUNK) +sizeof(WAV_DATA_CHUNK) + counter * pwfx->nBlockAlign;
                    header.audioFormat = wFormatTag;// Вообще то тройка здесь
    header.numChannels = pwfx->nChannels;
    header.sampleRate = pwfx->nSamplesPerSec;
    header.byteRate = pwfx->nAvgBytesPerSec;
    header.blockAlign = pwfx->nBlockAlign;
    header.bitsPerSample = pwfx->wBitsPerSample;
    fact.dwSampleLength = counter * pwfx->nChannels;
             data.subchunk2Size = counter * pwfx->nBlockAlign;// <------ получаеться размер в байтах
  //------------------------------------------------------------
       fseek(fp, 0, SEEK_SET);// SEEK_SET ---указатель положения в файле в начало файла
          res = fwrite(&header,WAVHEADER_SIZE,1,fp); //<------------писать WAVHEADER
    if(res<1)printf("header fwrite error!\n");
        res = fwrite(&fact,sizeof(fact),1,fp);
    if(res<1)printf("fact fwrite error!\n");
        res = fwrite(&data,sizeof(data),1,fp);
    if(res<1)printf("data fwrite error!\n");
//====================================================== END запись заголовка файла
Добавлено через 31 секунду
Где то так.

Добавлено через 28 минут
============ Кстати.... Оно, у вас, не всё читает.
Существует много разновидностей pcm файлов.

Добавлено через 46 секунд
у вас наверное свой вариант.

Добавлено через 9 минут
https://www.cyberforum.ru/atta... 1646859005
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.03.2022, 23:50
Помогаю со студенческими работами здесь

Частота звука в Wav файле (найти через Быстрое Преобразование Фурье)
Собственно, нужно найти частоту звука в Wav файле. Везде говорят о БПФ, но я нигде не нашел понятных новичку примеров. Нашел код для...

Обработка звука: в wav-файле удалить 20 секунд звукового файла из середины трека
Помогите с заданием, в файле с расширением Wav нужно удалить 20 секунд звукового файла из середины трека

Возпроизводство звука .wav при нажатии на кнопку
Читал, смотрел, пробовал - в итоге, теоретически, работает, но звука нету. Подскажите, чего может не хватает? Или в чём-либо есть ошибка?...

В файле удалить номера участников, оставив фамилию, имя в выходном файле
Нужна помощь в написании программы. Смысл программы таков: В входном текстовом документе, дан текст, вида: 412123412|pervii uchastnik; ...

Построить график звука из wav файла, преобразование Фурье, амплитуда и частота звука
Добрый день. У меня есть звук, который записан в wav файл(например 10 секунд). Нужно извлечь амплитуду и частоту, и по этим данным...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru