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

📄 sd2.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** Copyright (C) 2001-2004 Erik de Castro Lopo <erikd@mega-nerd.com>** Copyright (C) 2004 Paavo Jumppanen**** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU Lesser General Public License as published by** the Free Software Foundation; either version 2.1 of the License, or** (at your option) any later version.**** This program 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 Lesser General Public License for more details.**** You should have received a copy of the GNU Lesser General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*//*** The sd2 support implemented in this file was partially sponsored** (financially) by Paavo Jumppanen.*//*** Documentation on the Mac resource fork was obtained here :** http://developer.apple.com/documentation/mac/MoreToolbox/MoreToolbox-99.html*/#include	<stdio.h>#include	<stdlib.h>#include	<string.h>#include	<ctype.h>#include	"sndfile.h"#include	"config.h"#include	"sfendian.h"#include	"common.h"/*------------------------------------------------------------------------------ * Markers.*/#define	Sd2f_MARKER			MAKE_MARKER ('S', 'd', '2', 'f')#define	Sd2a_MARKER			MAKE_MARKER ('S', 'd', '2', 'a')#define	ALCH_MARKER			MAKE_MARKER ('A', 'L', 'C', 'H')#define lsf1_MARKER			MAKE_MARKER ('l', 's', 'f', '1')#define STR_MARKER			MAKE_MARKER ('S', 'T', 'R', ' ')#define sdML_MARKER			MAKE_MARKER ('s', 'd', 'M', 'L')enum{	RSRC_STR = 111,	RSRC_BIN} ;typedef struct{	unsigned char * rsrc_data ;	int rsrc_len ;	int data_offset, data_length ;	int map_offset, map_length ;	int type_count, type_offset ;	int item_offset ;	int str_index, str_count ;	int string_offset ;	/* All the above just to get these three. */	int sample_size, sample_rate, channels ;} SD2_RSRC ;typedef struct{	int type ;	int id ;	char name [32] ;	char value [32] ;	int value_len ;} STR_RSRC ;/*------------------------------------------------------------------------------ * Private static functions.*/static int sd2_close	(SF_PRIVATE *psf) ;static int sd2_parse_rsrc_fork (SF_PRIVATE *psf) ;static int parse_str_rsrc (SF_PRIVATE *psf, SD2_RSRC * rsrc) ;static int sd2_write_rsrc_fork (SF_PRIVATE *psf, int calc_length) ;/*------------------------------------------------------------------------------** Public functions.*/intsd2_open (SF_PRIVATE *psf){	int saved_filedes, subformat, error = 0 ;	/* SD2 is always big endian. */	psf->endian = SF_ENDIAN_BIG ;	if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->rsrclength > 0))	{	if (psf->rsrcdes < 0)	{	psf_log_printf (psf, "sd2_open : psf->rsrcdes < 0\n") ;		return SFE_SD2_BAD_RSRC ;		} ;		saved_filedes = psf->filedes ;		psf->filedes = psf->rsrcdes ;		error = sd2_parse_rsrc_fork (psf) ;		psf->filedes = saved_filedes ;		if (error)			goto error_cleanup ;		} ;	if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_SD2)	{	error = SFE_BAD_OPEN_FORMAT ;		goto error_cleanup ;		} ;	subformat = psf->sf.format & SF_FORMAT_SUBMASK ;	psf->dataoffset = 0 ;	/* Only open and write the resource in RDWR mode is its current length is zero. */	if (psf->mode == SFM_WRITE || (psf->mode == SFM_RDWR && psf->rsrclength == 0))	{	psf_open_rsrc (psf, psf->mode) ;		saved_filedes = psf->filedes ;		psf->filedes = psf->rsrcdes ;		error = sd2_write_rsrc_fork (psf, SF_FALSE) ;		psf->filedes = saved_filedes ;		if (error)			goto error_cleanup ;		/* Not needed. */		psf->write_header = NULL ;		} ;	psf->close = sd2_close ;	psf->blockwidth = psf->bytewidth * psf->sf.channels ;	switch (subformat)	{	case SF_FORMAT_PCM_S8 :	/* 8-bit linear PCM. */		case SF_FORMAT_PCM_16 :	/* 16-bit linear PCM. */		case SF_FORMAT_PCM_24 :	/* 24-bit linear PCM */				error = pcm_init (psf) ;				break ;		default :				error = SFE_UNIMPLEMENTED ;				break ;		} ;	psf_fseek (psf, psf->dataoffset, SEEK_SET) ;error_cleanup:	/* Close the resource fork regardless. We won't need it again. */	psf_close_rsrc (psf) ;	return error ;} /* sd2_open *//*------------------------------------------------------------------------------*/static intsd2_close	(SF_PRIVATE *psf){	if (psf->mode == SFM_WRITE)	{	/*  Now we know for certain the audio_length of the file we can re-write		**	correct values for the FORM, 8SVX and BODY chunks.		*/		} ;	return 0 ;} /* sd2_close *//*------------------------------------------------------------------------------*/static inline voidwrite_char (unsigned char * data, int offset, char value){	data [offset] = value ;} /* write_char */static inline voidwrite_short (unsigned char * data, int offset, short value){	data [offset] = value >> 8 ;	data [offset + 1] = value ;} /* write_char */static inline voidwrite_int (unsigned char * data, int offset, int value){	data [offset] = value >> 24 ;	data [offset + 1] = value >> 16 ;	data [offset + 2] = value >> 8 ;	data [offset + 3] = value ;} /* write_int */static voidwrite_str (unsigned char * data, int offset, char * buffer, int buffer_len){	memcpy (data + offset, buffer, buffer_len) ;} /* write_str */static intsd2_write_rsrc_fork (SF_PRIVATE *psf, int UNUSED (calc_length)){	SD2_RSRC rsrc ;	STR_RSRC str_rsrc [] =	{	{ RSRC_STR, 1000, "_sample-size", "", 0 },		{ RSRC_STR, 1001, "_sample-rate", "", 0 },		{ RSRC_STR, 1002, "_channels", "", 0 },		{ RSRC_BIN, 1000, "_Markers", "", 8 }		} ;	int k, str_offset, data_offset, next_str ;	memset (&rsrc, 0, sizeof (rsrc)) ;	rsrc.sample_rate = psf->sf.samplerate ;	rsrc.sample_size = psf->bytewidth ;	rsrc.channels = psf->sf.channels ;	rsrc.rsrc_data = psf->header ;	rsrc.rsrc_len = sizeof (psf->header) ;	memset (rsrc.rsrc_data, 0xea, rsrc.rsrc_len) ;	LSF_SNPRINTF (str_rsrc [0].value, sizeof (str_rsrc [0].value), "_%d", rsrc.sample_size) ;	LSF_SNPRINTF (str_rsrc [1].value, sizeof (str_rsrc [1].value), "_%d.000000", rsrc.sample_rate) ;	LSF_SNPRINTF (str_rsrc [2].value, sizeof (str_rsrc [2].value), "_%d", rsrc.channels) ;	for (k = 0 ; k < ARRAY_LEN (str_rsrc) ; k++)	{	if (str_rsrc [k].value_len == 0)		{	str_rsrc [k].value_len = strlen (str_rsrc [k].value) ;			str_rsrc [k].value [0] = str_rsrc [k].value_len - 1 ;			} ;		/* Turn name string into a pascal string. */		str_rsrc [k].name [0] = strlen (str_rsrc [k].name) - 1 ;		} ;	rsrc.data_offset = 0x100 ;	/*	** Calculate data length :	**		length of strings, plus the length of the sdML chunk.	*/	rsrc.data_length = 0 ;	for (k = 0 ; k < ARRAY_LEN (str_rsrc) ; k++)		rsrc.data_length += str_rsrc [k].value_len + 4 ;	rsrc.map_offset = rsrc.data_offset + rsrc.data_length ;	/* Very start of resource fork. */	write_int (rsrc.rsrc_data, 0, rsrc.data_offset) ;	write_int (rsrc.rsrc_data, 4, rsrc.map_offset) ;	write_int (rsrc.rsrc_data, 8, rsrc.data_length) ;	write_char (rsrc.rsrc_data, 0x30, strlen (psf->filename)) ;	write_str (rsrc.rsrc_data, 0x31, psf->filename, strlen (psf->filename)) ;	write_short (rsrc.rsrc_data, 0x50, 0) ;	write_int (rsrc.rsrc_data, 0x52, Sd2f_MARKER) ;	write_int (rsrc.rsrc_data, 0x56, lsf1_MARKER) ;	/* Very start of resource map. */	write_int (rsrc.rsrc_data, rsrc.map_offset + 0, rsrc.data_offset) ;	write_int (rsrc.rsrc_data, rsrc.map_offset + 4, rsrc.map_offset) ;	write_int (rsrc.rsrc_data, rsrc.map_offset + 8, rsrc.data_length) ;	/* These I don't currently understand. */	if (1)	{	write_char (rsrc.rsrc_data, rsrc.map_offset+ 16, 1) ;		/* Next resource map. */		write_int (rsrc.rsrc_data, rsrc.map_offset + 17, 0x12345678) ;		/* File ref number. */		write_short (rsrc.rsrc_data, rsrc.map_offset + 21, 0xabcd) ;		/* Fork attributes. */

⌨️ 快捷键说明

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