Russian Qt Forum
Ноябрь 24, 2024, 15:28 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Звук не воспроизводиться  (Прочитано 13431 раз)
BRE
Гость
« Ответ #15 : Январь 31, 2010, 12:50 »

Набросал небольшой пример, который читает и пишет WAV-файл.
Боевой код можно сделать проще, сейчас пытался расписать все в деталях.
Посмотри, попробуй. Когда разберешься, переделать код для mmio труда не составит.
Код
C++ (Qt)
// Код демонстрационный!      
// Код подразумевает, что архитектура использует byte order == little endian.
// При записи ошибки не проверяются, лениво стало. :)                        
 
#include <QByteArray>
#include <QFile>    
#include <QtEndian>  
#include <QDebug>    
 
#define SIG_RIFF        quint32(('R' << 24) | ('I' << 16) | ('F' << 8) | ('F'))
#define SIG_WAVE        quint32(('W' << 24) | ('A' << 16) | ('V' << 8) | ('E'))
#define SIG_FMT         quint32(('f' << 24) | ('m' << 16) | ('t' << 8) | (' '))
#define SIG_DATA        quint32(('d' << 24) | ('a' << 16) | ('t' << 8) | ('a'))
 
#pragma pack(push, 1)
struct WAVFormat    
{                    
       quint16 formatTag;                      // тип формата
       quint16 channels;                       // количество каналов (1 - моно или 2 - стeрео)
       quint32 samplesPerSec;          // частота дискретизации (11025, 22050, 44100, ...)    
       quint32 avgBytesPerSec;         // скорость потока данных                              
       quint16 blockAlign;                     // выравнивание блока данных                  
       quint16 bitsPerSample;          // количество бит в сеймпле                            
};                                                                                            
#pragma pack(pop)                                                                              
 
static bool findSig( QIODevice *dev, quint32 sig )
{                                                
       Q_ASSERT( dev );                          
 
       qDebug() << "Search signature :" << hex << sig;
 
       while( !dev->atEnd() )
       {                    
               quint32 data;
               if( dev->read( (char*)&data, sizeof( data ) ) != sizeof( data ) )
                       break;                                                  
               if( qToBigEndian( data ) == sig )                                
                       return true;                                            
       }                                                                        
       return false;                                                            
}                                                                                
 
QByteArray readWav( QIODevice *dev, WAVFormat &fmt )
{                                                  
       if( !dev )                                  
       {                                          
               qDebug() << "Device for reading is not specified";
               return QByteArray();                              
       }                                                        
 
       // Последовательно перемещаемся по сигнатурам RIFF, WAVE, fmt
       if( findSig( dev, SIG_RIFF ) && findSig( dev, SIG_WAVE ) && findSig( dev, SIG_FMT ) )
       {                                                                                    
               // Читаем и проверяем размер блока fmt                                      
               quint32 fmtSize;                                                            
               if( dev->read( (char*)&fmtSize, sizeof( fmtSize ) ) == sizeof( fmtSize ) && fmtSize == sizeof( fmt ) )
               {                                                                                                    
                       // Читаем блок fmt                                                                            
                       if( dev->read( (char*)&fmt, sizeof( fmt ) ) == sizeof( fmt ) )                                
                       {                                                                                            
                               // Перемещаемся к сигнатуре data                                                      
                               if( findSig( dev, SIG_DATA ) )                                                        
                               {                                                                                    
                                       // Читаем размер данных                                                      
                                       quint32 dataSize;                                                            
                                       if( dev->read( (char*)&dataSize, sizeof( dataSize ) ) == sizeof( dataSize ) )
                                       {                                                                            
                                               // Читаем блок данных                                                
                                               return dev->read( dataSize );                                        
                                       }                                                                            
                               }                                                                                    
                       }                                                                                            
               }                                                                                                    
       }                                                                                                            
 
       qDebug() << "Format file error";
       return QByteArray();            
}                                      
 
bool writeWav( QIODevice *dev, const WAVFormat &fmt, const QByteArray &data )
{                                                                            
       quint32 sig;                                                        
       quint32 size;                                                        
 
       if( !dev )
       {        
               qDebug() << "Device for writing is not specified";
               return false;                                    
       }                                                        
 
       // Пишем сигнатуру RIFF
       sig = qToBigEndian( SIG_RIFF );
       dev->write( (char*)&sig, sizeof( sig ) );
 
       // Вычисляем и записываем размер блока RIFF
       size = sizeof(quint32) +        // Сигнатура WAVE
                  sizeof(quint32) +    // Сигнатура fmt
                  sizeof(quint32) +    // Размер блока fmt (0x10)
                  sizeof(fmt) +                // Блок fmt      
                  sizeof(quint32) +    // Сигнатура data        
                  sizeof(quint32) +    // Размер данных          
                  data.size();                 // Длина данных  
       dev->write( (char*)&size, sizeof( size ) );              
 
       // Пишем сигнатуру WAVE
       sig = qToBigEndian( SIG_WAVE );
       dev->write( (char*)&sig, sizeof( sig ) );
 
       // Пишем сигнатуру fmt
       sig = qToBigEndian( SIG_FMT );
       dev->write( (char*)&sig, sizeof( sig ) );
 
       // Пишем размер блока fmt
       size = sizeof( fmt );    
       dev->write( (char*)&size, sizeof( size ) );
 
       // Пишем блок fmt
       dev->write( (char*)&fmt, sizeof( fmt ) );
 
       // Пишем сигнатуру data
       sig = qToBigEndian( SIG_DATA );
       dev->write( (char*)&sig, sizeof( sig ) );
 
       // Пишем размер data
       size = data.size();
       dev->write( (char*)&size, sizeof( size ) );
 
       // Пишем блок data
       dev->write( data );
 
       return true;
}                  
 
int main( int, char ** )
{                      
       // Читаем файл
       QFile infile( "test.wav" );
       if( !infile.open( QIODevice::ReadOnly ) )
       {
               qDebug() << "File open error";
               return 1;
       }
 
       WAVFormat fmt;
       QByteArray data = readWav( &infile, fmt );
       qDebug() << fmt.formatTag << fmt.channels << fmt.samplesPerSec << fmt.avgBytesPerSec << fmt.blockAlign << fmt.bitsPerSample;
 
       // Пишем файл
       QFile outfile( "out.wav" );
       if( !outfile.open( QIODevice::WriteOnly ) )
       {
               qDebug() << "File create error";
               return 1;
       }
 
       // Используем формат и данные прочитанного файла.
       // Если менять формат, то нужно настраивать параметры fmt и data.
       writeWav( &outfile, fmt, data );
 
       return 0;
}
 
Записан
Firefox
Гость
« Ответ #16 : Февраль 01, 2010, 08:45 »

спасибо,буду пробовать))
Записан
Firefox
Гость
« Ответ #17 : Февраль 03, 2010, 10:57 »

Со звуком всё разобрала, ещё раз благодарю. вот возникла другая проблемка. нужно чтобы по нажатию на кнопку громкость воспроизводимого файла(я его воспроизвожу с помощью QSound) менялась с каждым нажатием ну например уменьшалась. написала функцию
Код:
void cviaz_v::volum(DWORD RightVolume)
{
LPDWORD level;
HWAVEOUT id_pl;
int m_DeviceID;
WAVEOUTCAPS caps;
switch(waveOutGetDevCaps((UINT)id_pl, &caps,sizeof(caps)))
{
case MMSYSERR_NOERROR:
ui.text2_4->setText("1");
case MMSYSERR_BADDEVICEID:
ui.text2_4->setText("2");
case MMSYSERR_NODRIVER :
ui.text2_4->setText("3");
case MMSYSERR_NOMEM :
ui.text2_4->setText("4");

}
waveOutSetVolume(id_pl,0xFFFF-RightVolume);

}
но функция waveOutGetDevCaps должна возвращать первое значение блока case а заходит по очерёдно во все остальные. тоесть по логике получается что нет устройств на компьютере для воспроизведения музыки. но это явно не верно.
Записан
Kolobok
Гость
« Ответ #18 : Февраль 03, 2010, 12:24 »

В конце каждого блока case должен стоять break для выхода из switch.
Записан
Firefox
Гость
« Ответ #19 : Февраль 03, 2010, 13:39 »

break я поставлю. но функция waveOutGetDevCaps от эторго работать не станет. при правильной работе она должна вернуть MMSYSERR_NOERROR, но именно это значение она и не возвращает.
Записан
crackedmind
Гость
« Ответ #20 : Февраль 03, 2010, 14:14 »

Цитировать
   Identifier of the waveform-audio output device. It can be either a device identifier or a Handle to an open waveform-audio output device.
у вас же
Код:
HWAVEOUT id_pl;
никак не проинициализирован, т.е. устройство не открыто.
Записан
Firefox
Гость
« Ответ #21 : Февраль 03, 2010, 21:07 »

да вот это я тоже заметила, но как проинициализировать не зняю.подскажите пожалуйста
Записан
BRE
Гость
« Ответ #22 : Февраль 03, 2010, 21:15 »

да вот это я тоже заметила, но как проинициализировать не зняю.подскажите пожалуйста
А почему бы тебе не воспользоваться для этого Phonon'ом?
Записан
Firefox
Гость
« Ответ #23 : Февраль 16, 2010, 09:09 »

Код:
void SetVolume(unsigned int SetVolume)
{
WAVEOUTCAPSA Woc;

DWORD Volume ;

if(waveOutGetDevCapsA(WAVE_MAPPER, &Woc, sizeof(Woc)) ==

MMSYSERR_NOERROR)

if(Woc.dwSupport && WAVECAPS_VOLUME == WAVECAPS_VOLUME)

waveOutSetVolume(0, SetVolume);
}
если кому интересно вот функция для изменения громкости
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.195 секунд. Запросов: 20.