📄 sndheader.c
字号:
/* snd.c -- low-level sound I/O * * Roger Dannenberg * 21 Jun 1997 * * based on sndheader.c: * * Jim Zelenka, CMU/ITC, 9 Jun 1992 (rewritten from my old sources) * Roger Dannenberg, CMU, Mar 1993 (extensive changes and additions) * * and on sndread.c & sndwrite.c: * * Roger Dannenberg *//* Standard includes */#include <stdlib.h>#include <stdio.h>#include <string.h>#include "snd.h"#include "sndfileio.h"#include "sndheader.h"#include "ieeecvt.h"#include "sndhead.h"/* for HUGE_VAL: */#include "math.h"/* #define TRACE 1 */#ifdef LINUX# ifdef WIN32# error LINUX and WIN32 both?# endif// # include "sys/file.h"// # include <sys/stat.h># include <netinet/in.h>#else#ifndef WIN32# include <unistd.h>// # include <stat.h>// # include <fcntl.h>#else// # include <sys/stat.h>// # include "io.h"// # include "fcntl.h"# ifdef WINNT# include <winsock.h># else# include <winsock2.h># endif#endif#endif#ifndef min#define min(a, b) ((a) < (b) ? (a) : (b))#endif#define PERMISSION 0644 /* -rw-r--r-- *//* these macros are for byte ordering -- * doesn't the mac have std macros for this? *//* u_long PASCAL FAR ntohl(u_long netlong); */#ifdef MACINTOSH#define ntohs(x) (x)#define ntohl(x) (x)#define htons(x) (x)#define htonl(x) (x)#endif/* AIFF file Marker declaration */typedef struct { short id; long position;} marker_node, *marker_type;/* instrument definitions */typedef short marker_id;typedef struct { short play_mode; marker_id begin_loop; marker_id end_loop;} aiff_loop_node, *aiff_loop_type;typedef struct { char base_note; char detune; char low_note; char high_note; char low_velocity; char high_velocity; short gain; aiff_loop_node sustain_loop; aiff_loop_node release_loop;} inst_node;long snd_read_header(snd_type snd, long *flags);void snd_write_header(snd_type snd, long *flags);double read_ieee_extended(snd_type snd);void write_ieee_extended(int file, double x);void ConvertToIeeeExtended(double num, char *bytes);/* * reset the file to read from the beginning */void resetfile(int file){ snd_file_lseek(file, 0, SND_SEEK_SET);}/* * reads a an item of type T from F into L, if unsuccessful, * resets file to beginning and returns */#define readitem(F,L,T) { \ int r; \ r = snd_file_read(F, (char *) L,sizeof(T)); \ if (r != sizeof(T)) { resetfile(file); return *(L); } \ *read_in += sizeof(T); \}char readchar(int file, long *read_in){ char c = 0; readitem(file, &c, char); return c;}long readlong(int file, long *read_in){ long l = 0; readitem(file, &l, long); return ntohl(l);}short readshort(int file, long *read_in){ short s = 0; readitem(file, &s, short); return ntohs(s);}long revlong(long l){ return (((l >> 0) & 0xFF) << 24) | (((l >> 8) & 0xFF) << 16) | (((l >> 16) & 0xFF) << 8) | (((l >> 24) & 0xFF) << 0);}long readrevlong(int file, long *read_in){ return revlong(readlong(file, read_in));}short revshort(short s){ return ((s & 0xFF) << 8) | ((s >> 8) & 0xFF);}short readrevshort(int file, long *read_in){ return revshort(readshort(file, read_in));}float readfloat(int file, long *read_in){ float f = 0.0F; readitem(file, &f, float); return f;}unsigned char readuchar(int file, long *read_in){ unsigned char c = 0; readitem(file, &c, unsigned char); return c;}/* * write a an item of type T to F from L (no error handling yet) */#define writeitem(F,L,T) snd_file_write(F, (char *) L, sizeof(T));void writelong(int file, long l){ l = htonl(l); writeitem(file, &l, long);}void writeshort(int file, short s){ s = htons(s); writeitem(file, &s, short);}void writerevlong(int file, long l){ writelong(file, revlong(l));}void writerevshort(int file, short s){ writeshort(file, revshort(s));}void writefloat(int file, float f){ writeitem(file, &f, float);}void writeuchar(int file, unsigned char c){ writeitem(file, &c, unsigned char);}static int fail(snd_type snd, char *str){ resetfile(snd->u.file.file); snd->u.file.header = SND_HEAD_NONE; snd_fail(str); return !SND_SUCCESS;}void snd_open_fail(snd_type snd){ /* char msg[250]; */ snd->device = SND_DEVICE_NONE; snd->dictionary = &snd_none_dictionary; /* It's not fatal if the file does not exist... sprintf(msg, "snd_open: could not open file %s\n", snd->u.file.filename); snd_fail(msg); */ return;}int head_to_byteorder[] = { 0, 1, 1, 1, 0 };/* set_swap -- set the swap flag in snd *//**/void set_swap(snd_type snd){ int n = head_to_byteorder[snd->u.file.header]; if (snd->u.file.header == SND_HEAD_NONE) { /* go with whatever caller specified */ } else if (htonl(0x12345678) == 0x12345678) snd->u.file.swap = !n; else snd->u.file.swap = n;}int snd_open_file(snd_type snd, long *flags){ int file, rslt; if (snd->write_flag == SND_READ) { snd->u.file.loop_info = FALSE; file = snd_file_open(snd->u.file.filename, SND_RDONLY); snd->u.file.file = file; if (file < 0) { snd_open_fail(snd); return file; } rslt = snd_read_header(snd, flags); set_swap(snd); return rslt; } else if (snd->write_flag == SND_WRITE) { if (snd->u.file.header < 0 || snd->u.file.header >= SND_NUM_HEADS) { snd_fail("snd_open: invalid header value"); return !SND_SUCCESS; } file = snd_file_creat(snd->u.file.filename); snd->u.file.file = file; if (file < 0) { snd_open_fail(snd); return file; } /* special case: in WAV files, 8-bit PCM is stored as UPCM */ if (snd->u.file.header == SND_HEAD_WAVE && snd->format.mode == SND_MODE_PCM && snd->format.bits == 8) { snd->format.mode = SND_MODE_UPCM; } snd_write_header(snd, flags); } else if (snd->write_flag == SND_OVERWRITE) { file = snd_file_open(snd->u.file.filename, SND_RDWR); snd->u.file.file = file; if (file < 0) { snd_open_fail(snd); return file; } snd_file_lseek(file, snd->u.file.byte_offset, SND_SEEK_SET); snd->u.file.current_offset = snd->u.file.byte_offset; /* special case: in WAV files, 8-bit PCM is stored as UPCM */ if (snd->u.file.header == SND_HEAD_WAVE && snd->format.mode == SND_MODE_PCM && snd->format.bits == 8) { snd->format.mode = SND_MODE_UPCM; } } set_swap(snd); return SND_SUCCESS;}int snd_seek(snd_type snd, double when){ long offset_in_bytes = ((long) (when * snd->format.srate + 0.5)) * snd_bytes_per_frame(snd); long new_offset = snd->u.file.byte_offset + offset_in_bytes; if (new_offset > snd->u.file.end_offset) return !SND_SUCCESS; if (new_offset < snd->u.file.byte_offset) return !SND_SUCCESS; snd->u.file.current_offset = new_offset; if (snd_file_lseek(snd->u.file.file, new_offset, SND_SEEK_SET) == -1L) return !SND_SUCCESS; return SND_SUCCESS;}void readloop(aiff_loop_type loop, int file, long *read_in){ loop->play_mode = readshort(file, read_in); loop->begin_loop = readshort(file, read_in); loop->end_loop = readshort(file, read_in);}/* convert_loop_data -- from AIFF loop structure to snd loop structure *//**/void convert_loop_data(loop_type loop, aiff_loop_type aiffloop, marker_type markers, int nmarkers){ int i; loop->mode = aiffloop->play_mode; loop->begin = loop->end = -1; /* initialize to illegal value */ for (i = 0; i < nmarkers; i++) { if (aiffloop->begin_loop == markers[i].id) { loop->begin = markers[i].position; } if (aiffloop->end_loop == markers[i].id) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -