📄 alut.c
字号:
/**
* OpenAL cross platform audio library
* Copyright (C) 1999-2000 by authors.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* Or go to http://www.gnu.org/copyleft/lgpl.html
*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "alc.h"
typedef struct /* WAV File-header */
{
ALubyte Id[4];
ALsizei Size;
ALubyte Type[4];
} WAVFileHdr_Struct;
typedef struct /* WAV Fmt-header */
{
ALushort Format;
ALushort Channels;
ALuint SamplesPerSec;
ALuint BytesPerSec;
ALushort BlockAlign;
ALushort BitsPerSample;
} WAVFmtHdr_Struct;
typedef struct /* WAV FmtEx-header */
{
ALushort Size;
ALushort SamplesPerBlock;
} WAVFmtExHdr_Struct;
typedef struct /* WAV Smpl-header */
{
ALuint Manufacturer;
ALuint Product;
ALuint SamplePeriod;
ALuint Note;
ALuint FineTune;
ALuint SMPTEFormat;
ALuint SMPTEOffest;
ALuint Loops;
ALuint SamplerData;
struct
{
ALuint Identifier;
ALuint Type;
ALuint Start;
ALuint End;
ALuint Fraction;
ALuint Count;
} Loop[1];
} WAVSmplHdr_Struct;
typedef struct /* WAV Chunk-header */
{
ALubyte Id[4];
ALuint Size;
} WAVChunkHdr_Struct;
/* Default alignment */
/*
ALvoid alutInit(ALint *argc,ALbyte **argv)
{
ALCcontext *Context;
ALCdevice *Device;
//Open device
Device=alcOpenDevice((ALubyte*)"DirectSound3D");
//Create context(s)
Context=alcCreateContext(Device,NULL);
//Set active context
alcMakeContextCurrent(Context);
//Register extensions
}
ALvoid alutExit(ALvoid)
{
ALCcontext *Context;
ALCdevice *Device;
//Unregister extensions
//Get active context
Context=alcGetCurrentContext();
//Get device for active context
Device=alcGetContextsDevice(Context);
//Disable context
alcMakeContextCurrent(NULL);
//Release context(s)
alcDestroyContext(Context);
//Close device
alcCloseDevice(Device);
}
*/
ALvoid alutLoadWAVFile(ALbyte *file,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq, ALboolean *loop)
{
WAVChunkHdr_Struct ChunkHdr;
WAVFmtExHdr_Struct FmtExHdr;
WAVFileHdr_Struct FileHdr;
WAVSmplHdr_Struct SmplHdr;
WAVFmtHdr_Struct FmtHdr;
FILE *Stream;
*format=AL_FORMAT_MONO16;
*data=NULL;
*size=0;
*freq=22050;
*loop=AL_FALSE;
if (file)
{
Stream=fopen(file,"rb");
if (Stream)
{
fread(&FileHdr,1,sizeof(WAVFileHdr_Struct),Stream);
FileHdr.Size=((FileHdr.Size+1)&~1)-4;
while ((FileHdr.Size!=0)&&(fread(&ChunkHdr,1,sizeof(WAVChunkHdr_Struct),Stream)))
{
if (!memcmp(ChunkHdr.Id,"fmt ",4))
{
fread(&FmtHdr,1,sizeof(WAVFmtHdr_Struct),Stream);
if (FmtHdr.Format==0x0001)
{
*format=(FmtHdr.Channels==1?
(FmtHdr.BitsPerSample==8?AL_FORMAT_MONO8:AL_FORMAT_MONO16):
(FmtHdr.BitsPerSample==8?AL_FORMAT_STEREO8:AL_FORMAT_STEREO16));
*freq=FmtHdr.SamplesPerSec;
fseek(Stream,ChunkHdr.Size-sizeof(WAVFmtHdr_Struct),SEEK_CUR);
}
else
{
fread(&FmtExHdr,1,sizeof(WAVFmtExHdr_Struct),Stream);
fseek(Stream,ChunkHdr.Size-sizeof(WAVFmtHdr_Struct)-sizeof(WAVFmtExHdr_Struct),SEEK_CUR);
}
}
else if (!memcmp(ChunkHdr.Id,"data",4))
{
if (FmtHdr.Format==0x0001)
{
*size=ChunkHdr.Size;
*data=malloc(ChunkHdr.Size+31);
if (*data) fread(*data,FmtHdr.BlockAlign,ChunkHdr.Size/FmtHdr.BlockAlign,Stream);
memset(((char *)*data)+ChunkHdr.Size,0,31);
}
else if (FmtHdr.Format==0x0011)
{
//IMA ADPCM
}
else if (FmtHdr.Format==0x0055)
{
//MP3 WAVE
}
}
else if (!memcmp(ChunkHdr.Id,"smpl",4))
{
fread(&SmplHdr,1,sizeof(WAVSmplHdr_Struct),Stream);
*loop = (SmplHdr.Loops ? AL_TRUE : AL_FALSE);
fseek(Stream,ChunkHdr.Size-sizeof(WAVSmplHdr_Struct),SEEK_CUR);
}
else fseek(Stream,ChunkHdr.Size,SEEK_CUR);
fseek(Stream,ChunkHdr.Size&1,SEEK_CUR);
FileHdr.Size-=(((ChunkHdr.Size+1)&~1)+8);
}
fclose(Stream);
}
}
}
ALvoid alutLoadWAVMemory(ALbyte *memory,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq,ALboolean *loop)
{
WAVChunkHdr_Struct ChunkHdr;
WAVFmtExHdr_Struct FmtExHdr;
WAVFileHdr_Struct FileHdr;
WAVSmplHdr_Struct SmplHdr;
WAVFmtHdr_Struct FmtHdr;
ALbyte *Stream;
*format=AL_FORMAT_MONO16;
*data=NULL;
*size=0;
*freq=22050;
*loop=AL_FALSE;
if (memory)
{
Stream=memory;
if (Stream)
{
memcpy(&FileHdr,Stream,sizeof(WAVFileHdr_Struct));
Stream+=sizeof(WAVFileHdr_Struct);
FileHdr.Size=((FileHdr.Size+1)&~1)-4;
while ((FileHdr.Size!=0)&&(memcpy(&ChunkHdr,Stream,sizeof(WAVChunkHdr_Struct))))
{
Stream+=sizeof(WAVChunkHdr_Struct);
if (!memcmp(ChunkHdr.Id,"fmt ",4))
{
memcpy(&FmtHdr,Stream,sizeof(WAVFmtHdr_Struct));
if (FmtHdr.Format==0x0001)
{
*format=(FmtHdr.Channels==1?
(FmtHdr.BitsPerSample==8?AL_FORMAT_MONO8:AL_FORMAT_MONO16):
(FmtHdr.BitsPerSample==8?AL_FORMAT_STEREO8:AL_FORMAT_STEREO16));
*freq=FmtHdr.SamplesPerSec;
Stream+=ChunkHdr.Size;
}
else
{
memcpy(&FmtExHdr,Stream,sizeof(WAVFmtExHdr_Struct));
Stream+=ChunkHdr.Size;
}
}
else if (!memcmp(ChunkHdr.Id,"data",4))
{
if (FmtHdr.Format==0x0001)
{
*size=ChunkHdr.Size;
*data=malloc(ChunkHdr.Size+31);
if (*data) memcpy(*data,Stream,ChunkHdr.Size);
memset(((char *)*data)+ChunkHdr.Size,0,31);
Stream+=ChunkHdr.Size;
}
else if (FmtHdr.Format==0x0011)
{
//IMA ADPCM
}
else if (FmtHdr.Format==0x0055)
{
//MP3 WAVE
}
}
else if (!memcmp(ChunkHdr.Id,"smpl",4))
{
memcpy(&SmplHdr,Stream,sizeof(WAVSmplHdr_Struct));
*loop = (SmplHdr.Loops ? AL_TRUE : AL_FALSE);
Stream+=ChunkHdr.Size;
}
else Stream+=ChunkHdr.Size;
Stream+=ChunkHdr.Size&1;
FileHdr.Size-=(((ChunkHdr.Size+1)&~1)+8);
}
}
}
}
ALvoid alutUnloadWAV(ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
{
if (data)
free(data);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -