转载:WAV header
转自:http://www.cnblogs.com/CoderTian/p/6657844.html
WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource Interchange File Format)文件规范,用于保存Windows平台的音频信息资源,被Windows平台及其应用程序所广泛支持。WAVE文件通常只是一个具有单个“WAVE”块的RIFF文件,该块由两个子块(”fmt”子数据块和”data”子数据块),它的格式如下图所示
该格式的实质就是在PCM文件的前面加了一个文件头,每个字段的的含义为
typedef struct{
char ChunkID[4];//内容为"RIFF"
unsigned long ChunkSize;//存储文件的字节数(不包含ChunkID和ChunkSize这8个字节)
char Format[4];//内容为"WAVE"
}WAVE_HEADER;
typedef struct{
char Subchunk1ID[4];//内容为"fmt"
unsigned long Subchunk1Size;//存储该子块的字节数(不含前面的Subchunk1ID和Subchunk1Size这8个字节)
unsigned short AudioFormat;//存储音频文件的编码格式,例如若为PCM则其存储值为1,若为其他非PCM格式的则有一定的压缩。
unsigned short NumChannels;//通道数,单通道(Mono)值为1,双通道(Stereo)值为2,等等
unsigned long SampleRate;//采样率,如8k,44.1k等
unsigned long ByteRate;//每秒存储的bit数,其值=SampleRate * NumChannels * BitsPerSample/8
unsigned short BlockAlign;//块对齐大小,其值=NumChannels * BitsPerSample/8
unsigned short BitsPerSample;//每个采样点的bit数,一般为8,16,32等。
}WAVE_FMT;
typedef struct{
char Subchunk2ID[4];//内容为“data”
unsigned long Subchunk2Size;//内容为接下来的正式的数据部分的字节数,其值=NumSamples * NumChannels * BitsPerSample/8
}WAVE_DATA;
比如下面的例子
这里是一个WAVE文件的开头72字节,字节显示为十六进制数字:
52 49 46 46 24 08 00 00 57 41 56 45 66 6d 74 20 10 00 00 00 01 00 02 00
22 56 00 00 88 58 01 00 04 00 10 00 64 61 74 61 00 08 00 00 00 00 00 00
24 17 1e f3 3c 13 3c 14 16 f9 18 f9 34 e7 23 a6 3c f2 24 f2 11 ce 1a 0d
字段解析:
pcm 加上WAV header的代码实现为
int simplest_pcm16le_to_wave(const char *pcmpath,int channels,int sample_rate,const char *wavepath)
{
typedef struct WAVE_HEADER{
char fccID[4];
unsigned long dwSize;
char fccType[4];
}WAVE_HEADER;
typedef struct WAVE_FMT{
char fccID[4];
unsigned long dwSize;
unsigned short wFormatTag;
unsigned short wChannels;
unsigned long dwSamplesPerSec;
unsigned long dwAvgBytesPerSec;
unsigned short wBlockAlign;
unsigned short uiBitsPerSample;
}WAVE_FMT;
typedef struct WAVE_DATA{
char fccID[4];
unsigned long dwSize;
}WAVE_DATA;
if(channels==0||sample_rate==0){
channels = 2;
sample_rate = 44100;
}
int bits = 16;
WAVE_HEADER pcmHEADER;
WAVE_FMT pcmFMT;
WAVE_DATA pcmDATA;
unsigned short m_pcmData;
FILE *fp,*fpout;
fp=fopen(pcmpath, "rb");
if(fp == NULL) {
printf("open pcm file error\n");
return -1;
}
fpout=fopen(wavepath, "wb+");
if(fpout == NULL) {
printf("create wav file error\n");
return -1;
}
//WAVE_HEADER
memcpy(pcmHEADER.fccID,"RIFF",strlen("RIFF"));
memcpy(pcmHEADER.fccType,"WAVE",strlen("WAVE"));
fseek(fpout,sizeof(WAVE_HEADER),1);
//WAVE_FMT
pcmFMT.dwSamplesPerSec=sample_rate;
pcmFMT.dwAvgBytesPerSec=pcmFMT.dwSamplesPerSec*sizeof(m_pcmData);
pcmFMT.uiBitsPerSample=bits;
memcpy(pcmFMT.fccID,"fmt ",strlen("fmt "));
pcmFMT.dwSize=16;
pcmFMT.wBlockAlign=2;
pcmFMT.wChannels=channels;
pcmFMT.wFormatTag=1;
fwrite(&pcmFMT,sizeof(WAVE_FMT),1,fpout);
//WAVE_DATA;
memcpy(pcmDATA.fccID,"data",strlen("data"));
pcmDATA.dwSize=0;
fseek(fpout,sizeof(WAVE_DATA),SEEK_CUR);
fread(&m_pcmData,sizeof(unsigned short),1,fp);
while(!feof(fp)){
pcmDATA.dwSize+=2;
fwrite(&m_pcmData,sizeof(unsigned short),1,fpout);
fread(&m_pcmData,sizeof(unsigned short),1,fp);
}
pcmHEADER.dwSize=44+pcmDATA.dwSize;
rewind(fpout);
fwrite(&pcmHEADER,sizeof(WAVE_HEADER),1,fpout);
fseek(fpout,sizeof(WAVE_FMT),SEEK_CUR);
fwrite(&pcmDATA,sizeof(WAVE_DATA),1,fpout);
fclose(fp);
fclose(fpout);
return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<pthread.h>
typedef struct{
char chunkId[];//"RIFF"
unsigned long chunkSize;
char format[];//"WAVE"
}WAVE_RIFF;
typedef struct{
char chunkId[];//"fmt"
unsigned long chunkSize;
unsigned short audioFormat;
unsigned short chNum;
unsigned long sampleRate;
unsigned long byteRate;//SampleRate * NumChannels * BitsPerSample/8
unsigned short blockAlign;//NumChannels * BitsPerSample/8
unsigned short bitsPerSample;//8,16,32
}WAVE_FMT;
typedef struct{
char chunkId[];//"data"
unsigned long chunkSize;//NumSamples * NumChannels * BitsPerSample/8
}WAVE_DATA;
typedef struct
{
char fileName[];
FILE *fp;
long pos;
unsigned long totalSampleNum;
WAVE_RIFF riffChunk;
WAVE_FMT fmtChunk;
WAVE_DATA dataChunk;
}WAVE_INFO; #define READ_SAMPLES 256
#define PP_SAMPLES 64
typedef struct
{
unsigned short chNum;
unsigned short bankNum;
unsigned long samplesPerBank;
unsigned short bytesPerSample;
unsigned short bankRp;
unsigned short bankWp;
unsigned char ***pData;
unsigned char fgEos;
}PP_BUF_T; PP_BUF_T gPpBuf;
unsigned char fgEnd = ;
void printWaveHeader(WAVE_INFO *pWaveInfo)
{
printf("fileName:%s\n", pWaveInfo->fileName);
printf("riff chunk:\n");
printf("chunkId:%c%c%c%c\n", pWaveInfo->riffChunk.chunkId[], pWaveInfo->riffChunk.chunkId[], pWaveInfo->riffChunk.chunkId[], pWaveInfo->riffChunk.chunkId[]);
printf("chunkSize:%ld\n", pWaveInfo->riffChunk.chunkSize);
printf("format:%c%c%c%c\n", pWaveInfo->riffChunk.format[], pWaveInfo->riffChunk.format[], pWaveInfo->riffChunk.format[], pWaveInfo->riffChunk.format[]);
printf("fmt chunk:\n");
printf("chunkId:%c%c%c\n", pWaveInfo->fmtChunk.chunkId[], pWaveInfo->fmtChunk.chunkId[], pWaveInfo->fmtChunk.chunkId[]);
printf("chunkSize:%ld\n", pWaveInfo->fmtChunk.chunkSize);
printf("audioFormat:%d\n", pWaveInfo->fmtChunk.audioFormat);
printf("chNum:%d\n", pWaveInfo->fmtChunk.chNum);
printf("sampleRate:%ld\n", pWaveInfo->fmtChunk.sampleRate);
printf("byteRate:%ld\n", pWaveInfo->fmtChunk.byteRate);
printf("blockAlign:%d\n", pWaveInfo->fmtChunk.blockAlign);
printf("bitsPerSample:%d\n", pWaveInfo->fmtChunk.bitsPerSample);
printf("data chunk:\n");
printf("chunkId:%c%c%c%c\n", pWaveInfo->dataChunk.chunkId[], pWaveInfo->dataChunk.chunkId[], pWaveInfo->dataChunk.chunkId[], pWaveInfo->dataChunk.chunkId[]);
printf("chunkSize:%ld\n", pWaveInfo->dataChunk.chunkSize); }
void initWaveInfo(WAVE_INFO *pWaveInfo, unsigned short chNum, unsigned long sampleRate, unsigned short bitsPerSample)
{
//strncpy(pWaveInfo->riffChunk.chunkId, "RIFF", 4);
pWaveInfo->riffChunk.chunkId[] = 'R';
pWaveInfo->riffChunk.chunkId[] = 'I';
pWaveInfo->riffChunk.chunkId[] = 'F';
pWaveInfo->riffChunk.chunkId[] = 'F';
pWaveInfo->riffChunk.chunkSize = ;
//strncpy(pWaveInfo->riffChunk.format, "WAVE", 4);
pWaveInfo->riffChunk.format[] = 'W';
pWaveInfo->riffChunk.format[] = 'A';
pWaveInfo->riffChunk.format[] = 'V';
pWaveInfo->riffChunk.format[] = 'E';
//strncpy(pWaveInfo->fmtChunk.chunkId, "fmt", 3);
pWaveInfo->fmtChunk.chunkId[] = 'f';
pWaveInfo->fmtChunk.chunkId[] = 'm';
pWaveInfo->fmtChunk.chunkId[] = 't';
pWaveInfo->fmtChunk.chunkId[] = ' ';
pWaveInfo->fmtChunk.chunkSize = sizeof(WAVE_FMT) - ;
pWaveInfo->fmtChunk.audioFormat = ;
pWaveInfo->fmtChunk.chNum = chNum;
pWaveInfo->fmtChunk.sampleRate = sampleRate;
pWaveInfo->fmtChunk.byteRate = sampleRate * chNum * bitsPerSample / ;
pWaveInfo->fmtChunk.blockAlign = chNum * bitsPerSample / ;
pWaveInfo->fmtChunk.bitsPerSample = bitsPerSample;
//strncpy(pWaveInfo->dataChunk.chunkId, "data", 4);
pWaveInfo->dataChunk.chunkId[] = 'd';
pWaveInfo->dataChunk.chunkId[] = 'a';
pWaveInfo->dataChunk.chunkId[] = 't';
pWaveInfo->dataChunk.chunkId[] = 'a'; pWaveInfo->dataChunk.chunkSize = ;
pWaveInfo->totalSampleNum = ;
///printWaveHeader(pWaveInfo);
} void rwRiffChunk(WAVE_INFO *pWaveInfo, unsigned char fgRead)
{
if (fgRead)
{
fread((char *)&pWaveInfo->riffChunk.chunkId, , , pWaveInfo->fp);
fread((char *)&pWaveInfo->riffChunk.chunkSize, , , pWaveInfo->fp);
fread((char *)&pWaveInfo->riffChunk.format, , , pWaveInfo->fp);
}
else
{
fwrite((char *)&pWaveInfo->riffChunk.chunkId, , , pWaveInfo->fp);
fwrite((char *)&pWaveInfo->riffChunk.chunkSize, , , pWaveInfo->fp);
fwrite((char *)&pWaveInfo->riffChunk.format, , , pWaveInfo->fp);
}
}
void rwFmtChunk(WAVE_INFO *pWaveInfo, unsigned char fgRead)
{
if (fgRead)
{
fread((char *)&pWaveInfo->fmtChunk.chunkId, , , pWaveInfo->fp);
fread((char *)&pWaveInfo->fmtChunk.chunkSize, , , pWaveInfo->fp);
fread((char *)&pWaveInfo->fmtChunk.audioFormat, , , pWaveInfo->fp);
fread((char *)&pWaveInfo->fmtChunk.chNum, , , pWaveInfo->fp);
fread((char *)&pWaveInfo->fmtChunk.sampleRate, , , pWaveInfo->fp);
fread((char *)&pWaveInfo->fmtChunk.byteRate, , , pWaveInfo->fp);
fread((char *)&pWaveInfo->fmtChunk.blockAlign, , , pWaveInfo->fp);
fread((char *)&pWaveInfo->fmtChunk.bitsPerSample, , , pWaveInfo->fp);
}
else
{
fwrite((char *)&pWaveInfo->fmtChunk.chunkId, , , pWaveInfo->fp);
fwrite((char *)&pWaveInfo->fmtChunk.chunkSize, , , pWaveInfo->fp);
fwrite((char *)&pWaveInfo->fmtChunk.audioFormat, , , pWaveInfo->fp);
fwrite((char *)&pWaveInfo->fmtChunk.chNum, , , pWaveInfo->fp);
fwrite((char *)&pWaveInfo->fmtChunk.sampleRate, , , pWaveInfo->fp);
fwrite((char *)&pWaveInfo->fmtChunk.byteRate, , , pWaveInfo->fp);
fwrite((char *)&pWaveInfo->fmtChunk.blockAlign, , , pWaveInfo->fp);
fwrite((char *)&pWaveInfo->fmtChunk.bitsPerSample, , , pWaveInfo->fp); }
}
void rwDataChunk(WAVE_INFO *pWaveInfo, unsigned char fgRead)
{
if (fgRead)
{
fread((char *)&pWaveInfo->dataChunk.chunkId, , , pWaveInfo->fp);
fread((char *)&pWaveInfo->dataChunk.chunkSize, , , pWaveInfo->fp);
}
else
{
fwrite((char *)&pWaveInfo->dataChunk.chunkId, , , pWaveInfo->fp);
fwrite((char *)&pWaveInfo->dataChunk.chunkSize, , , pWaveInfo->fp);
}
} void readWaveHeader(char *fileName, WAVE_INFO *pWaveInfo)
{
size_t retSize;
strncpy(pWaveInfo->fileName, fileName, strlen(fileName));
pWaveInfo->fp = fopen(fileName, "rb");
if (pWaveInfo->fp == NULL)
{
printf("fopen fail, errno:%d\n", errno);
return;
}
#if 0
retSize = fread((char *)&pWaveInfo->riffChunk, sizeof(WAVE_RIFF), , pWaveInfo->fp);
retSize = fread((char *)&pWaveInfo->fmtChunk, sizeof(WAVE_FMT), , pWaveInfo->fp);
retSize = fread((char *)&pWaveInfo->dataChunk, sizeof(WAVE_DATA), , pWaveInfo->fp);
#endif
rwRiffChunk(pWaveInfo, );
rwFmtChunk(pWaveInfo, );
rwDataChunk(pWaveInfo, );
pWaveInfo->pos = ftell(pWaveInfo->fp);
pWaveInfo->totalSampleNum = pWaveInfo->dataChunk.chunkSize / (pWaveInfo->fmtChunk.bitsPerSample / );
fclose(pWaveInfo->fp);
printWaveHeader(pWaveInfo);
} void initPpBuf(unsigned short chNum, unsigned short bankNum, unsigned long samplesPerBank, unsigned short bytesPerSample)
{
unsigned short chIdx, bankIdx;
gPpBuf.chNum = chNum;
gPpBuf.bankNum = bankNum;
gPpBuf.samplesPerBank = samplesPerBank;
gPpBuf.bytesPerSample = bytesPerSample; gPpBuf.bankRp = gPpBuf.bankWp = ;
gPpBuf.fgEos = ;
gPpBuf.pData = (unsigned char ***)malloc(chNum * sizeof(unsigned char **));
for (chIdx = ; chIdx < chNum; chIdx++)
{
gPpBuf.pData[chIdx] = (unsigned char **)malloc(bankNum * sizeof(unsigned char *));
for (bankIdx =; bankIdx < bankNum; bankIdx++)
{
gPpBuf.pData[chIdx][bankIdx] = (unsigned char *) malloc(samplesPerBank * bytesPerSample * sizeof(unsigned char));
}
}
} int sendData(unsigned char *writeBuffer, unsigned short chNum)
{
unsigned short sampleIdx, chIdx, byteIdx;
printf("sendData, wp:%d, rp:%d\n", gPpBuf.bankWp, gPpBuf.bankRp);
if ((gPpBuf.bankWp + ) % gPpBuf.bankNum == gPpBuf.bankRp)
{
//full
return ;
}
else
{
for (sampleIdx = ; sampleIdx < PP_SAMPLES; sampleIdx++)
{
for (chIdx =; chIdx < chNum; chIdx++)
{
for (byteIdx = ; byteIdx < gPpBuf.bytesPerSample; byteIdx++)
{
gPpBuf.pData[chIdx][gPpBuf.bankWp][sampleIdx * gPpBuf.bytesPerSample + byteIdx] = writeBuffer[(chIdx + sampleIdx * chNum) * gPpBuf.bytesPerSample + byteIdx];
}
}
}
gPpBuf.bankWp = (gPpBuf.bankWp + ) % gPpBuf.bankNum;
}
return ;
} int recvData(unsigned char **readBuffer)
{
unsigned short chIdx;
printf("recvData, wp:%d, rp:%d\n", gPpBuf.bankWp, gPpBuf.bankRp);
if (gPpBuf.bankWp == gPpBuf.bankRp)
{
//empty
return ;
}
else
{
for (chIdx = ; chIdx < gPpBuf.chNum; chIdx++)
{
memcpy(&readBuffer[chIdx][], &gPpBuf.pData[chIdx][gPpBuf.bankRp][], PP_SAMPLES * gPpBuf.bytesPerSample * sizeof(unsigned char));
}
gPpBuf.bankRp = (gPpBuf.bankRp + ) % gPpBuf.bankNum;
}
return ;
}
void *readThread(void *arg)
{
char *fileName = (char *)arg;
size_t retSize;
WAVE_INFO waveInfo;
memset(&waveInfo, , sizeof(WAVE_INFO));
unsigned long bytesPerLoop;
unsigned short loopIdx, loop;
unsigned long readCount = ;
readWaveHeader(fileName, &waveInfo);
unsigned long readSize = READ_SAMPLES * waveInfo.fmtChunk.chNum * waveInfo.fmtChunk.bitsPerSample / ;
printf("readSize:%ld\n", readSize);
unsigned char *readBuffer = (unsigned char *)malloc(readSize * sizeof(unsigned char));
waveInfo.fp = fopen(fileName, "rb");
fseek(waveInfo.fp, waveInfo.pos, SEEK_SET);
while ()
{
retSize = fread(readBuffer, readSize, , waveInfo.fp);
if (retSize <= )
{
printf("fread fail,retSize:%d, %s, eof:%d, readCount:%ld\n", (int) retSize, strerror(errno), feof(waveInfo.fp), readCount);
gPpBuf.fgEos = ;
break;
}
else
{
bytesPerLoop = PP_SAMPLES *waveInfo.fmtChunk.chNum * waveInfo.fmtChunk.bitsPerSample / ;
loop = readSize / bytesPerLoop;
loopIdx = ;
while (loopIdx < loop)
{
if ( != sendData(readBuffer + loopIdx * bytesPerLoop, waveInfo.fmtChunk.chNum))
{
usleep();
}
else
{
loopIdx++;
}
}
readCount++;
}
}
return NULL;
}
void pp()
{
} void saveOneChInWave(unsigned char *pData, unsigned long size, WAVE_INFO *pWaveInfo)
{
size_t retSize = ;
if (pWaveInfo->fp == NULL)
{
pWaveInfo->fp = fopen(pWaveInfo->fileName, "wb");
#if 0
retSize = fwrite((char *)&pWaveInfo->riffChunk, sizeof(WAVE_RIFF), , pWaveInfo->fp);
retSize = fwrite((char *)&pWaveInfo->fmtChunk, sizeof(WAVE_FMT), , pWaveInfo->fp);
retSize = fwrite((char *)&pWaveInfo->dataChunk, sizeof(WAVE_DATA), , pWaveInfo->fp);
#endif
rwRiffChunk(pWaveInfo, );
rwFmtChunk(pWaveInfo, );
rwDataChunk(pWaveInfo, );
}
retSize = fwrite(pData, size, , pWaveInfo->fp);
pWaveInfo->totalSampleNum += (size / pWaveInfo->fmtChunk.chNum / (pWaveInfo->fmtChunk.bitsPerSample / ));
pWaveInfo->pos = ftell(pWaveInfo->fp);
} void updateWaveHeader(WAVE_INFO *pWaveInfo)
{
size_t retSize;
pWaveInfo->riffChunk.chunkSize = pWaveInfo->pos - ;
pWaveInfo->dataChunk.chunkSize = pWaveInfo->totalSampleNum * pWaveInfo->fmtChunk.chNum * pWaveInfo->fmtChunk.bitsPerSample / ;
fseek(pWaveInfo->fp, , SEEK_SET);
#if 0
retSize = fwrite((char *)&pWaveInfo->riffChunk, sizeof(WAVE_RIFF), , pWaveInfo->fp);
retSize = fwrite((char *)&pWaveInfo->fmtChunk, sizeof(WAVE_FMT), , pWaveInfo->fp);
retSize = fwrite((char *)&pWaveInfo->dataChunk, sizeof(WAVE_DATA), , pWaveInfo->fp);
#endif
rwRiffChunk(pWaveInfo, );
rwFmtChunk(pWaveInfo, );
rwDataChunk(pWaveInfo, );
fclose(pWaveInfo->fp); printWaveHeader(pWaveInfo);
}
void *ppThread(void *arg)
{
char *fileName = (char *)arg;
WAVE_INFO waveInfo;
memset(&waveInfo, , sizeof(waveInfo));
strncpy(waveInfo.fileName, fileName, strlen(fileName));
printf("out file:%s\n", waveInfo.fileName);
waveInfo.fp = NULL;
initWaveInfo(&waveInfo, , , );
unsigned char **readBuffer = (unsigned char **)malloc(gPpBuf.chNum * sizeof(unsigned char *));
unsigned short chIdx;
for(chIdx = ; chIdx < gPpBuf.chNum; chIdx++)
{
readBuffer[chIdx] = (unsigned char *)malloc(PP_SAMPLES * gPpBuf.bytesPerSample * sizeof(unsigned char));
}
while ()
{
if ( != recvData(readBuffer))
{
if (gPpBuf.fgEos)
break;
usleep();
}
else
{
saveOneChInWave(readBuffer[], PP_SAMPLES * gPpBuf.bytesPerSample, &waveInfo);
pp();
}
}
updateWaveHeader(&waveInfo);
fgEnd = ;
} int main(int argc, char **argv)
{
#if 0
WAVE_INFO inputWaveInfo, outputWaveInfo;
readWaveHeader(argv[], &inputWaveInfo);
//initWaveInfo(&outputWaveInfo, 2, 48000, 16);
#endif #if 1
pthread_t readThreadId, ppThreadId;
initPpBuf(, , PP_SAMPLES, );
pthread_create(&readThreadId, NULL, readThread, argv[]);
pthread_create(&ppThreadId, NULL, ppThread, argv[]);
while(!fgEnd)
{
sleep();
}
#endif
return ;
}
转载:WAV header的更多相关文章
- [转载]C header files matching your running
原文地址:C header files matching your running kernel were not found.作者:[Opser]小默 c header files matching ...
- C++标准库实现WAV文件读写
在上一篇文章RIFF和WAVE音频文件格式中对WAV的文件格式做了介绍,本文将使用标准C++库实现对数据为PCM格式的WAV文件的读写操作,只使用标准C++库函数,不依赖于其他的库. WAV文件结构 ...
- WAV文件格式解析及处理
RIFF file format RIFF全称为资源互换文件格式(Resources Interchange File Format),是Windows下大部分多媒体文件遵循的一种文件结构.RIFF文 ...
- vs2010音频文件压缩 调用lame_enc.dll将WAV格式转换成MP3
/* //My_lame.h */ #pragma once#include "stdafx.h"#include <windows.h>#include <st ...
- wav音频文件头解析
wav概述 WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(ResourceInterchange File Format)文件规范,用于保存Windows平台的音频信息 ...
- 永不消逝的电波(二)HackRF入门:家用无线门铃信号重放
0×00 前言 在第一篇文章:永不消逝的电波(一):无线电入门篇 我们了解了一下无线电的发展史以及无线电的一些物理知识,在第二篇里我们将用HackRF录制家用门铃的无线信号,然后重放门铃信号. 门铃从 ...
- IE8 CSS hack 测试
IE8正式版出来有一段日子了,但是针对ie8正式版的CSS hack却很少,其实这是值得庆幸的,因为ie8修复了很多IE6和IE7的一些BUG,更加接近W3C标准.针对IE8正式版的CSS hack目 ...
- IE8 CSS hack
IE8正式版出来有一段日子了,但是针对ie8正式版的CSS hack却很少,其实这是值得庆幸的,因为ie8修复了很多IE6和IE7的一些BUG,更加接近W3C标准. 针对IE8正式版的CSS hack ...
- Android : 基于alsa库的音乐播放
继上篇:Android : alsa-lib 移植 ,这篇随笔实现一个demo基于移植好的alsa库在Android平台上播放wav文件: 一.利用ffmeg将一个mp3文件转换成wav文件: (1) ...
随机推荐
- 实用技巧之while里面使用getchar或sleep函数
我们经常需要打印一些变量的取值来调试程序,使用while(1)是常用的手段. ) { char letter = getchar(); printf("test_point is %d \t ...
- Java代码手段防止非法请求——防盗链
Java代码手段防止非法请求,思路如下: 1. 获取到当前请求的域名,如www.a.com 2. 获取到请求资源的上一个地址 3. 判断上一个地址是否为空,如 ...
- Selenium3+python自动化013-自动化数据驱动及模型介绍
一.查看当前运行的浏览等相关信息 driver=webdriver.Chrome() print(driver.capabilities["version"]) #浏览器版本 pr ...
- Nessus安装出现localhost:8834无法访问
1.下载Nessus https://www.tenable.com/downloads/nessus#download 2.安装方法 详细安装方法参考下文 https://www.ld80.cn/a ...
- TP-网页静态化
首先放上一张某手册中的一段代码: 我们要想在TP框架中执行网页静态化,在这段代码的基础上稍加添加就可以了: 在TP5框架中,为了方便寻找模板文件与生成的静态文件,我们将模板文件以及生成的静态文件放在p ...
- 0007 settings.py配置文件详解
01 DEBUG调试配置 开发期设置为True,发布时设置为False 02 INSTALLED_APPS已安装的APP配置 INSTALLED_APPS = [ 'django.contrib.ad ...
- ubuntu18+caffe+cuda
昨天安装caffe,因为用的是cuda10.2,遇到各种问题,最终也没有安装成功.使用cmake配置成功.生成成功.编译的时候报错. /usr/local/cuda/include/cuda_runt ...
- CSS技巧!鼠标经过图片抖动效果
把代码加到style.css(模板的主css里面): /**图片抖动**/ img:hover{-webkit-animation: tada 1s .2s ease both;-moz-animat ...
- NMF: non-negative matrix factorization.
1. 矩阵分解可以用来解决什么方法, 以及how? 利用矩阵分解来解决实际问题的分析方法很多,如PCA(主成分分析).ICA(独立成分分析).SVD(奇异值分解).VQ(矢量量化)等.在所有这些方法中 ...
- Hibernate的基本工作原理
Hibernate开发过程中会用到5个核心接口: 1.Configuration2.SessionFactory3.Session4.Transaction5.QueryHibernate就是通过这些 ...