首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >u-law压缩返回无效文件c++。

u-law压缩返回无效文件c++。
EN

Stack Overflow用户
提问于 2020-03-08 21:34:58
回答 1查看 136关注 0票数 0

我正在尝试将u-law算法应用于wav文件file.wav,然后创建一个新的文件file2.wavfile.wav有16位/样本,我想获得一个有8位/样本的file2.wav

这是我的密码:

代码语言:javascript
复制
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <iostream>
#include <string>
#include <fstream>

using namespace std;
using std::string;
using std::fstream;

typedef struct  WAV_HEADER {
    char                RIFF[4];
    unsigned long       ChunkSize;
    char                WAVE[4];
    char                fmt[4];
    unsigned long       Subchunk1Size;
    unsigned short      AudioFormat;
    unsigned short      NumOfChan;
    unsigned long       SamplesPerSec;
    unsigned long       bytesPerSec;
    unsigned short      blockAlign;
    unsigned short      bitsPerSample;
    char                Subchunk2ID[4];
    unsigned long       Subchunk2Size;

} wav_hdr;

int headerSize = 0;
string path = "file.wav";
wav_hdr wavHeader;

FILE* openFile() {
    const char* filePath;
    FILE *wavFile;

    headerSize = sizeof(wav_hdr);
    filePath = path.c_str();
    wavFile = fopen(filePath, "rb");

    if (wavFile == NULL) {
        printf("Error\n");
    }

    fread(&wavHeader, headerSize, 1, wavFile);

    return wavFile;
}

int8_t MuLaw_Encode(int16_t number)
{
    const uint16_t MULAW_MAX = 0x1FFF;
    const uint16_t MULAW_BIAS = 33;
    uint16_t mask = 0x1000;
    uint8_t sign = 0;
    uint8_t position = 12;
    uint8_t lsb = 0;
    if (number < 0)
    {
        number = -number;
        sign = 0x80;
    }
    number += MULAW_BIAS;
    if (number > MULAW_MAX)
    {
        number = MULAW_MAX;
    }
    for (; ((number & mask) != mask && position >= 5); mask >>= 1, position--)
        ;
    lsb = (number >> (position - 4)) & 0x0f;
    return (~(sign | ((position - 5) << 4) | lsb));
}

int fileSize(FILE *file) {
    int fileSize = 0;

    fseek(file, 0, SEEK_END);
    fileSize = ftell(file);
    fseek(file, 0, SEEK_SET);

    return fileSize;
}

double bitsPerSample() {
    double bitsPerE;

    bitsPerE = wavHeader.bitsPerSample;
    return bitsPerE;
}

int main() {
    FILE *wavFile;
    wavFile = openFile();
    FILE* fptr2;
    fptr2 = fopen("file2.wav", "wb");

    int samples_count = fileSize(wavFile) / bitsPerSample();
    short int *value = new short int[samples_count];

    for (int16_t i = 0; i < samples_count; i++)
    {
        fread(&value[i], samples_count, 1, wavFile);
        cout << value[i] << " "; // the output is in the attached picture
        MuLaw_Encode(value[i]);
    }
        fwrite(value, sizeof(char), samples_count, fptr2);

    return 0;
}

我采用了这里 (2.1 )中的u-law算法。规则压缩(编码)算法

我做错了什么吗?因为我得到了一个损坏的文件。

EN

回答 1

Stack Overflow用户

发布于 2020-03-08 21:51:55

没有任何头写入结果文件,因此数据的第一部分将被解释为头,这将是错误的。您可以在文件中看到,它没有以RIFFþR�WAVEfmt或其他类似的东西开头。

写入结果文件的数据是value,是从输入文件中读取的原始数据,而不是经过cout编码的数据(只有cout'ed而没有保存)。

读取样本的循环读取一些错误的样本,因为samples_count的计算将当前位置放回头所在的起始位置。

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

https://stackoverflow.com/questions/60592288

复制
相关文章

相似问题

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