首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >文件操作到QByteArray操作?

文件操作到QByteArray操作?
EN

Stack Overflow用户
提问于 2015-12-06 03:51:25
回答 1查看 344关注 0票数 2

我有以下代码将原始音频文件转换为wav文件:

代码语言:javascript
复制
int MainWindow::rawToWav(const char *rawfn, const char *wavfn, long samplingRate)
{
    long chunksize=0x10;
    int statusCollect = 0;
    struct
    {
        unsigned short    wFormatTag;
        unsigned short    wChannels;
        unsigned long     dwSamplesPerSec;
        unsigned long     dwAvgBytesPerSec;
        unsigned short    wBlockAlign;
        unsigned short    wBitsPerSample;
    } fmt;

    errno_t err;
    FILE *raw;
    err = fopen_s(&raw, rawfn, "rb");
    if(!raw)
        return -2;

    fseek(raw, 0, SEEK_END);
    long bytes = ftell(raw);
    fseek(raw, 0, SEEK_SET);

    long samplecount = bytes/2;
    long riffsize    = samplecount*2+0x24;
    long datasize    = samplecount*2;

    FILE *wav;
    err = fopen_s(&wav, wavfn, "wb");
    if(!wav)
    {
        fclose(raw);
        return -3;
    }

    fwrite( "RIFF",     1, 4, wav );
    fwrite( &riffsize,  4, 1, wav );
    fwrite( "WAVEfmt ", 1, 8, wav );
    fwrite( &chunksize, 4, 1, wav );

    int bitsPerSample = 16;
    int bytesPerSample = bitsPerSample/8;
    int channel = 2;

    fmt.wFormatTag = 1;      // PCM
    fmt.wChannels  = channel;      // MONO
    fmt.dwSamplesPerSec  = samplingRate;
    fmt.dwAvgBytesPerSec = samplingRate*channel*bytesPerSample; // 16 bit
    fmt.wBlockAlign      = channel*bytesPerSample;
    fmt.wBitsPerSample   = bitsPerSample;

    fwrite( &fmt,      sizeof(fmt), 1, wav );
    fwrite( "data",    1,           4, wav );
    fwrite( &datasize, 4,           1, wav );
    short buff[1024];
    while( !feof(raw) )
    {
        int cnt=fread(buff,2,1024,raw);
        if( cnt == 0 )
            break;
        fwrite(buff,2,cnt,wav);
    }
    statusCollect = fclose( raw );
    statusCollect += fclose( wav );
    return statusCollect;
}

我想要的操作完全相同,不是对文件类型的数据,而是对QByteArray类型。

所以我正在尝试下面的方法。首先,我尝试在QByteArray对象上添加wav头。然后我将原始音频文件上传到程序中。然后我将原始数据添加到我已经添加了wav头的QByteArray对象中。然后将QByteArray保存为wav文件。

代码语言:javascript
复制
void MainWindow::rawToWavQT(QByteArray* arr, long samplingRate, long sizeOfRawFile)
{
    long chunksize=0x10;
    struct
    {
        unsigned short    wFormatTag;
        unsigned short    wChannels;
        unsigned long     dwSamplesPerSec;
        unsigned long     dwAvgBytesPerSec;
        unsigned short    wBlockAlign;
        unsigned short    wBitsPerSample;
    } fmt;

    long samplecount = sizeOfRawFile/2;
    long riffsize    = samplecount*2+0x24;
    long datasize    = samplecount*2;

    arr->append("RIFF");//    fwrite( "RIFF",     1, 4, wav );
    arr->append((const char*)&riffsize);//    fwrite( &riffsize,  4, 1, wav );
    arr->append("WAVEfmt ");//    fwrite( "WAVEfmt ", 1, 8, wav );
    arr->append((const char*)&chunksize);//    fwrite( &chunksize, 4, 1, wav );

    int bitsPerSample = 16;
    int bytesPerSample = bitsPerSample/8;
    int channel = 2;

    fmt.wFormatTag = 1;      // PCM
    fmt.wChannels  = channel;      // MONO
    fmt.dwSamplesPerSec  = samplingRate;
    fmt.dwAvgBytesPerSec = samplingRate*channel*bytesPerSample; // 16 bit
    fmt.wBlockAlign      = channel*bytesPerSample;
    fmt.wBitsPerSample   = bitsPerSample;

    arr->append((const char*)&fmt);//    fwrite( &fmt,      sizeof(fmt), 1, wav );
    arr->append("data");//    fwrite( "data",    1,           4, wav );
    arr->append((const char*)&datasize);//    fwrite( &datasize, 4,           1, wav );
}

但是这种将头添加到QByteArray中然后添加原始数据的方式并不能产生正确类型的wav文件,因为它无法播放。您认为从第二个函数中判断我做了什么错误?在第二个函数中,我所做的操作与对第一个函数的操作相同,但对QByteArray对象而不是对文件对象?

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-06 04:14:29

您的数据连接函数只需在第一个空字节处停止,就会丢失重要数据并破坏对齐。相反,您希望以类似于fwrite的方式指定要附加的长度。解决方案:将append()语句从单个const char *参数替换为使用数据和数据长度构造的QByteArray语句。

变化

代码语言:javascript
复制
arr->append((const char*)&riffsize);

代码语言:javascript
复制
arr->append(QByteArray((const char*)&riffsize, 4));

同样,对于其他原始数据,append语句也是如此。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34113822

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档