⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soundfile.cpp

📁 一个语言识别引擎
💻 CPP
字号:
// -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-

/*
 * This file has been modified for the yarp.
 *
 * The behaviour and appearence of the program code below can differ to a major
 * extent from the version distributed by the original author(s).
 *
 */

/* @(#)wav.c	1.4 01/10/27 Copyright 1998,1999 Heiko Eissfeldt */
/***
 * CopyPolicy: GNU Public License 2 applies
 * Copyright (C) by Heiko Eissfeldt
 *
 *
 */

// Summary for YARP:
// Copyright: 1998,1999 Heiko Eissfeldt


#include <ace/OS.h>
#include <yarp/os/NetInt32.h>
#include <yarp/sig/Sound.h>
#include <yarp/sig/SoundFile.h>
#include <yarp/os/ManagedBytes.h>

using namespace yarp::os;
using namespace yarp::sig;
using namespace yarp::sig::file;

typedef short NetInt16; // need to add this to yarp, do right thing everywhere
typedef NetInt32 FOURCC;

typedef struct CHUNKHDR {
    FOURCC ckid;	/* chunk ID */
    NetInt32 dwSize; 	/* chunk size */
} CHUNKHDR;

/* flags for 'wFormatTag' field of WAVEFORMAT */
#define WAVE_FORMAT_PCM 1

/* specific waveform format structure for PCM data */
typedef struct pcmwaveformat_tag {
    NetInt16 wFormatTag;	/* format type */
    NetInt16 nChannels;	/* number of channels (i.e. mono, stereo, etc.) */
    NetInt32 nSamplesPerSec; /* sample rate */
    NetInt32  nAvgBytesPerSec; /* for buffer size estimate */
    NetInt16  nBlockAlign;     /* block size of data */
    NetInt16 wBitsPerSample;
} PCMWAVEFORMAT;
typedef PCMWAVEFORMAT *PPCMWAVEFORMAT;

// noops when NetInt32 and NetInt16 do right thing
#define cpu_to_le32(x) (x)
#define cpu_to_le16(x) (x)

/* MMIO macros */
#define mmioFOURCC(ch0, ch1, ch2, ch3) \
  ((NetInt32)((unsigned int)(unsigned char)(ch0) | ((unsigned int)(unsigned char)(ch1) << 8) | \
  ((unsigned int)(unsigned char)(ch2) << 16) | ((unsigned int)(unsigned char)(ch3) << 24)))

#define FOURCC_RIFF	mmioFOURCC ('R', 'I', 'F', 'F')
#define FOURCC_LIST	mmioFOURCC ('L', 'I', 'S', 'T')
#define FOURCC_WAVE	mmioFOURCC ('W', 'A', 'V', 'E')
#define FOURCC_FMT	mmioFOURCC ('f', 'm', 't', ' ')
#define FOURCC_DATA	mmioFOURCC ('d', 'a', 't', 'a')


/* simplified Header for standard WAV files */
typedef struct WAVEHDR {
    CHUNKHDR chkRiff;
    FOURCC fccWave;
    CHUNKHDR chkFmt;
    NetInt16 wFormatTag;	/* format type */
    NetInt16 nChannels;	/* number of channels (i.e. mono, stereo, etc.) */
    NetInt32 nSamplesPerSec; /* sample rate */
    NetInt32 nAvgBytesPerSec;/* for buffer estimation */
    NetInt16 nBlockAlign;	/* block size of data */
    NetInt16 wBitsPerSample;
    CHUNKHDR chkData;
} WAVEHDR;

#define IS_STD_WAV_HEADER(waveHdr) ( \
  waveHdr.chkRiff.ckid == FOURCC_RIFF && \
  waveHdr.fccWave == FOURCC_WAVE && \
  waveHdr.chkFmt.ckid == FOURCC_FMT && \
  waveHdr.chkData.ckid == FOURCC_DATA && \
  waveHdr.wFormatTag == WAVE_FORMAT_PCM)


static int _InitSound (WAVEHDR& waveHdr ,
                       long channels , 
                       unsigned long rate , 
                       long nBitsPerSample , 
                       unsigned long expected_bytes ) {
    unsigned long nBlockAlign = channels * ((nBitsPerSample + 7) / 8);
    unsigned long nAvgBytesPerSec = nBlockAlign * rate;
    unsigned long temp = expected_bytes + sizeof(WAVEHDR) - sizeof(CHUNKHDR);

    waveHdr.chkRiff.ckid    = cpu_to_le32(FOURCC_RIFF);
    waveHdr.fccWave         = cpu_to_le32(FOURCC_WAVE);
    waveHdr.chkFmt.ckid     = cpu_to_le32(FOURCC_FMT);
    waveHdr.chkFmt.dwSize   = cpu_to_le32(sizeof (PCMWAVEFORMAT));
    waveHdr.wFormatTag      = cpu_to_le16(WAVE_FORMAT_PCM);
    waveHdr.nChannels       = (NetInt16) cpu_to_le16(channels);
    waveHdr.nSamplesPerSec  = cpu_to_le32(rate);
    waveHdr.nBlockAlign     = (NetInt16) cpu_to_le16(nBlockAlign);
    waveHdr.nAvgBytesPerSec = cpu_to_le32(nAvgBytesPerSec);
    waveHdr.wBitsPerSample  = (NetInt16) cpu_to_le16(nBitsPerSample);
    waveHdr.chkData.ckid    = cpu_to_le32(FOURCC_DATA);
    waveHdr.chkRiff.dwSize  = cpu_to_le32(temp);
    waveHdr.chkData.dwSize  = cpu_to_le32(expected_bytes);
    return 0;
}


bool yarp::sig::file::read(Sound& dest, const char *src) {
    WAVEHDR waveHdr;
	FILE *fp = ACE_OS::fopen(src, "rb");
	if (!fp) {
        ACE_OS::printf("cannot open file %s for reading\n", src);
        return false;
    }
    ACE_OS::fread(&waveHdr,sizeof(waveHdr),1,fp);
    int freq = waveHdr.nSamplesPerSec;
    int channels = waveHdr.nChannels;
    int expect = waveHdr.chkData.dwSize;
    int bits = waveHdr.wBitsPerSample;
    if (bits!=16) {
        ACE_OS::printf("sorry, lousy wav read code only does 16-bit ints\n");
        return false;
    }
    int samples = (expect/2)/channels;
    printf("%d channels %d samples %d frequency\n",
           channels, samples, freq);
    dest.resize(samples,channels);
    dest.setFrequency(freq);

    /*
      if (expect!=dest.getRawDataSize()) {
      printf("expect to read %ld bytes but would read %ld\n",
      dest.getRawDataSize(), expect);
      ACE_OS::fclose(fp);
      return false;
      }
      fread(dest.getRawData(),dest.getRawDataSize(),1,fp);
    */

    ManagedBytes bytes(expect);
    fread(bytes.get(),bytes.length(),1,fp);
    NetInt16 *data = (NetInt16*)bytes.get();
    int ct = 0;
    for (int i=0; i<samples; i++) {
        for (int j=0; j<channels; j++) {
            dest.set(data[ct],i,j);
            ct++;
        }
    }

    ACE_OS::fclose(fp);
    return false;
}

bool yarp::sig::file::write(const Sound& src, const char *dest) {
    WAVEHDR waveHdr;
    int expect = src.getChannels()*src.getSamples()*2;
    _InitSound(waveHdr,
               src.getChannels(),
               (int)src.getFrequency(),
               16,
               expect);
    
	FILE *fp = ACE_OS::fopen(dest, "wb");
	if (!fp) {
        ACE_OS::printf("cannot open file %s for writing\n", dest);
        return false;
    }
    /*
      if (expect!=src.getRawDataSize()) {
      printf("expect to write %ld bytes but would write %ld\n",
      expect, src.getRawDataSize());
      ACE_OS::fclose(fp);
      return false;
      }
    */

    ACE_OS::fwrite((void*)&waveHdr, 1, sizeof(waveHdr), fp);


    ManagedBytes bytes(expect);
    NetInt16 *data = (NetInt16*)bytes.get();
    int ct = 0;
    int samples = src.getSamples();
    int channels = src.getChannels();
    for (int i=0; i<samples; i++) {
        for (int j=0; j<channels; j++) {
            int v = src.get(i,j);
            data[ct] = v;
            ct++;
        }
    }
    fwrite(bytes.get(),bytes.length(),1,fp);

    /*
      ACE_OS::fwrite((void*)src.getRawData(), (size_t)src.getRawDataSize(), 
      1, fp);
    */
    ACE_OS::fclose(fp);
    return true;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -