Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.01.2013, 23:23   #1
Mago
Пользователь
 
Регистрация: 24.07.2008
Сообщений: 23
По умолчанию Работа со звуком.

В общем, мне нужно реализовать обычное эхо в некомпрессированном wav файле со звуком и сохранить в новый файл. Но при добавлении появляется шум! Обычное ли это явление, или я что-то делаю не так?
В моём примере пытаюсь сделать задержку в 1 секунду.
Привожу код:
Код:
#include <stdio.h>
#include <iostream> 
#include <Windows.h>
#include <tchar.h>
#include <conio.h>
#include <math.h>
#include <fstream>
using namespace std;
void main (void)
{
 	setlocale(LC_ALL,"Russian"); //Локаль
	ifstream file("C:\\ok.wav",ios::beg | ios::in|ios::binary); //Наша wav'ка
	
	DWORD dwRIFF = 0; //И так идет формат wav-файла, он относится к RIFF-файлам, поэтому читаем 4 байта структуы
    file.read((char*) &dwRIFF,4);
    if (dwRIFF != MAKEFOURCC('R','I','F','F')) //Если RIFF не получили, то значит какую то залепу открыли
    {
        cout<<"Файл не является RIFF - formated"<<endl;
		system("pause");
        return;
    }

	long chunkSize = 0;
	file.read((char*)&chunkSize,4);
	cout<<"chunkSize = "<<chunkSize<<endl;
	
    DWORD dwWave = 0; //Секция WAVE
    file.read((char*)&dwWave,4); //Читаем 4 байта, там для Wav-файла должно быть название секции WAVE
    if (dwWave != MAKEFOURCC('W','A','V','E')) //Проверим
    {
        cout<<"Файл не имеет секции WAVE"<<endl;
		system("pause");
        return;
    }

    DWORD dwFormat = 0; // Секция fmt /формат файла/
    file.read((char*)&dwFormat,4); //Если все ОК... То читаем 
    if (dwFormat != MAKEFOURCC('f','m','t',' ')) //Если секция fmt - не найдена 
    {
        cout<<"Файл не имеет Format(fmt)-Секции "<<endl;
		system("pause");
        return;
    }

	long  lSizeFmt = 0; //Размер секции fmt
	file.read((char*)&lSizeFmt,4);
	cout<<"lSizeFmt = "<<lSizeFmt<<endl;

	long  audioFormat = 0;
	file.read((char*)&audioFormat,2);
	cout<<"audioFormat = "<<audioFormat<<endl;

	long numChannels = 0;
	file.read((char*)&numChannels,2);
	cout<<"numChannels = "<<numChannels<<endl;
	
	long sampleRate = 0;
	file.read((char*)&sampleRate,4);
	cout<<"sampleRate = "<<sampleRate<<endl;

	long byteRate = 0;
	file.read((char*)&byteRate,4);
	cout<<"byteRate = "<<byteRate<<endl;

	long blockAlign = 0;
	file.read((char*)&blockAlign,2);
	cout<<"blockAlign = "<<blockAlign<<endl;
	
	long bitsPerSample = 0;
	file.read((char*)&bitsPerSample,2);
	cout<<"bitsPerSample = "<<bitsPerSample<<endl;

	DWORD dwSection = 0; //Следующая секция у нас data(это как раз наш звук)
    file.read((char*)&dwSection,4); //Читаем заголовок
	if (dwSection != MAKEFOURCC('d','a','t','a')) //Ну а теперь сама data - это то, над чем мы будем работать
    {
        cout<<"Не найдена секция data"<<endl;
		system("pause");
        return;
    }
	
	long dwDataSize = 0; 
    file.read((char*)&dwDataSize,4);
	cout<<"dwDataSize = "<<dwDataSize<<endl;

	char *pData = new char[dwDataSize]; //Динамически выделим переменную типа char[размер звуковых данных]
	file.read (pData, dwDataSize); //Прочитаем в нее все звуковые данные
	
	file.close();

	char *pDataEcho = new char [dwDataSize + int (1 * byteRate)]; 
    memset (pDataEcho, 0, dwDataSize + 1 * byteRate); 
	signed long sum;
//////////Далее самое главное - делаем эхо///////////
    for (int i = 0; i < dwDataSize; i++) 
    {
		pDataEcho [i] += pData [i];
		pDataEcho [i + int (1 * byteRate)] += pData[i];
    }
    long dwDataSize2 = 0;
	dwDataSize2 = dwDataSize + 1 * byteRate;

	long chunkSize2 = dwDataSize2 + 36;

	ofstream file2("C:\\ok2.wav",ios::beg | ios::out|ios::binary);

	file2.write((char*)&dwRIFF,4);
	file2.write((char*)&chunkSize2,4);
	file2.write((char*)&dwWave,4);
	file2.write((char*)&dwFormat,4);
	file2.write((char*)&lSizeFmt,4);
	file2.write((char*)&audioFormat,2);
	file2.write((char*)&numChannels,2);
	file2.write((char*)&sampleRate,4);
	file2.write((char*)&byteRate,4);
	file2.write((char*)&blockAlign,2);
	file2.write((char*)&bitsPerSample,2);
	file2.write((char*)&dwSection,4);
	file2.write((char*)&dwDataSize2,4);
	file2.write(pDataEcho, dwDataSize2);

	file2.close();
	delete pDataEcho;
	delete pData;
	system("pause");
}
Mago вне форума Ответить с цитированием
Старый 30.01.2013, 23:43   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Когда складываем два char-а результат может не поместится в char (clipping)
waleri на форуме Ответить с цитированием
Старый 31.01.2013, 00:41   #3
Mago
Пользователь
 
Регистрация: 24.07.2008
Сообщений: 23
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Когда складываем два char-а результат может не поместится в char (clipping)
Завтра поработаю над этим, сообщу о результате.
Mago вне форума Ответить с цитированием
Старый 31.01.2013, 00:57   #4
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Вроде бы микшировать надобно с ослабленным сигналом и без постоянной составляющей. Условный нуль == 127
EUGY вне форума Ответить с цитированием
Старый 31.01.2013, 01:35   #5
Mago
Пользователь
 
Регистрация: 24.07.2008
Сообщений: 23
По умолчанию

Цитата:
Сообщение от EUGY Посмотреть сообщение
Вроде бы микшировать надобно с ослабленным сигналом и без постоянной составляющей. Условный нуль == 127
А можно простенький пример на языке программирования? Недопонимаю что-то уже. Весь день сижу.
Mago вне форума Ответить с цитированием
Старый 31.01.2013, 13:54   #6
Mago
Пользователь
 
Регистрация: 24.07.2008
Сообщений: 23
По умолчанию

Спасибо, waleri! Вы были правы, формат char мутил что-то непонятное, когда сумма была больше 127. Помогла такая проверка с дополнительной переменной:

Код:
signed long sum = 0;
for (int i = 0; i < dwDataSize; i++) 
{
	sum = pDataEcho [i];
	sum += pData [i];
	if (sum > 127)
		sum = 127;
	if (sum < -128)
		sum = -128;
	pDataEcho [i] = sum;
	pDataEcho [i + int (1 * byteRate)] += pData[i];
}

Но, в принципе, как сказал EUGY, помогло бы, видимо, и ослабление сигнала.

Последний раз редактировалось Mago; 31.01.2013 в 13:55. Причина: Забыл
Mago вне форума Ответить с цитированием
Старый 31.01.2013, 13:59   #7
Mago
Пользователь
 
Регистрация: 24.07.2008
Сообщений: 23
По умолчанию

А, поторопился. При уменьшении времени задержки вновь сильный шум и треск Разбираюсь далее.
Mago вне форума Ответить с цитированием
Старый 31.01.2013, 14:31   #8
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Шум и треск - похоже гдето осталась неинициализированная память?
waleri на форуме Ответить с цитированием
Старый 31.01.2013, 15:05   #9
Mago
Пользователь
 
Регистрация: 24.07.2008
Сообщений: 23
По умолчанию

Нужно, видимо, понять, как представляются данные о звуке в этих массивах. Просто пройдясь по собранному pData и умножив каждый элемент на 0.5, звук не только становится тише, но и появляется шум.
Mago вне форума Ответить с цитированием
Старый 31.01.2013, 18:20   #10
Mago
Пользователь
 
Регистрация: 24.07.2008
Сообщений: 23
По умолчанию

Подозреваю, что это связано битностью, количеством каналов и частотой дискретизации. Но разобраться не могу
Mago вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа со звуком bonjovi Паскаль, Turbo Pascal, PascalABC.NET 14 12.02.2012 19:04
Работа со звуком Drulya C# (си шарп) 4 12.09.2011 11:58
работа со звуком Garic_ Помощь студентам 19 15.12.2009 19:39
Работа со звуком Claptrap Мультимедиа в Delphi 7 06.11.2009 13:42
Работа со звуком Claster Мультимедиа в Delphi 1 19.05.2009 13:28