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

📄 adpcmtec.c

📁 arm ads1.2 with crack.rar
💻 C
字号:
/*
 * Adaptive Differential Pulse Code Modulation test harness
 * Copyright (C) ARM Limited 1998-1999. All rights reserved.
 */

#include <stdlib.h>

#include "adpcmc.h"
#include "adpcms.h"

#include "adpcmtec.h"

#include "errorc.h"
#include "fileutlc.h"
#include "optionsc.h"

#define ADPCM_OPTIONS	4

static void Menu( unsigned int numberOptions ) ;
static Boolean PerformADPCMARM( short outputs[ ], short inputs[ ], unsigned int nInputs, Boolean encode ) ;
static Boolean PerformADPCMC( short outputs[ ], short inputs[ ], unsigned int nInputs, Boolean encode ) ;
static Boolean Transform( unsigned int option ) ;

/**** adpcm_main ********************************************************************
 *
 * Version & Date
 * -------   ----
 * 1.0.0, 30/06/1998
 *
 * Description
 * -----------
 * initialise the application then loop whilst the user is still working
 *
 * Return Values
 * ------ ------
 *     0 - application terminated correctly
 *     1 - some error occurred
 *
 * History (with dates)
 * -------  ---- -----
 * 1.0.0, 30/06/1998    first release
 *
 ************************************************************************************/
int adpcm_main( int argc, char **argv )
{
	unsigned int	option ;
#ifdef	__BIG_ENDIAN
	char			newStdIn[ ] = "stdinb" ;
	char			newStdOut[ ] = "stdoutb" ;
	char			newStdErr[ ] = "stderrb" ;
#else
	char			newStdIn[ ] = "stdinl" ;
	char			newStdOut[ ] = "stdoutl" ;
	char			newStdErr[ ] = "stderrl" ;
#endif
	unsigned int	stdio = 0 ;
	
	if( ChangeStdIO( &argc, &argv, newStdIn, stdin ) == STDINID ) {
		stdio |= ( 1 << STDINID ) ;
	}
	if( ChangeStdIO( &argc, &argv, newStdOut, stdout ) == STDOUTID ) {
		stdio |= ( 1 << STDOUTID ) ;
	}
	if( ChangeStdIO( &argc, &argv, newStdErr, stderr ) == STDERRID ) {
		stdio |= ( 1 << STDERRID ) ;
	}
	
	printf( "Program to perform ADPCM.\n\n" ) ;
	
	printf( "This application provides access to the ADPCM with 16 bit binary input data.\n\n" ) ;
	
	while( 1 ) {
		if( ( option = NextTask( ADPCM_OPTIONS, &Menu ) ) == 0 ) {
			break ;
		}
		
		Transform( option ) ;
	}
	
	/* redirection based on trying to open files that don't exist do using defaults */
	if( stdio & ( 1 << STDINID ) ) {
		ResetStdIO( stdin ) ;
	}
	if( stdio & ( 1 << STDOUTID ) ) {
		ResetStdIO( stdout ) ;
	}
	if( stdio & ( 1 << STDERRID ) ) {
		ResetStdIO( stderr ) ;
	}
	
	return 0 ;
}

/**** Menu **************************************************************************
 *
 * Version & Date
 * -------   ----
 * 1.0.0, 30/06/1998
 *
 * Description
 * -----------
 * print the menu of options to the screen (defined in standard way for NextTask 
 * function and will be called by NextTask)
 *
 * Inputs
 * ------
 *   numberOptions
 *   - the number of menu options that should be printed
 *
 * History (with dates)
 * -------  ---- -----
 * 1.0.0, 30/06/1998    first release
 *
 ************************************************************************************/
static void Menu( unsigned int numberOptions )
{
	if( numberOptions == ADPCM_OPTIONS ) {
		printf( " 1. Forward ARM Assembler ADPCM followed by inverse ARM Assembler ADPCM.\n" ) ;
		printf( " 2. Forward C ADPCM followed by inverse C ADPCM.\n" ) ;
		printf( " 3. Forward ARM Assembler ADPCM followed by inverse C ADPCM.\n" ) ;
		printf( " 4. Forward C ADPCM followed by inverse ARM Assembler ADPCM.\n" ) ;
	}
	else {
		fprintf( stderr, "[Menu] Error in arguments, aborting.\n\n" ) ;
		/* function name given since intended as internal error for programmer */
	}
}

/**** PerformADPCM ******************************************************************
 *
 * Version & Date
 * -------   ----
 * 1.0.0, 30/06/1998
 *
 * Description
 * -----------
 * given an array of data values, either PCM or ADPCM, encode or decode them into
 * their corresponding ADPCM or PCM values respectively and return these new values
 *
 * Inputs
 * ------
 *   inputs
 *   - an array referencing the inputs either PCM or ADPCM samples
 *   nInputs
 *   - the number of data points referenced by the array inputs
 *   arm
 *   - true  : use ARM Assembler routines to encode or decode
 *     false : use C routines to encode or decode
 *   encode
 *   - true  : values given are PCM samples and are to be encoded
 *     false : values given are ADPCM samples and are to be decoded
 * Return Values
 * ------ ------
 *     short * - an array of samples
 *               if encode = true array contains encoded ADPCM samples
 *               if encode = false array contains decoded PCM sampled
 *     NULL    - some error occurred (memory allocation failed?)
 *
 * Memory allocated (not deallocated)
 * ------ ---------  --- -----
 * the returned array of shorts
 * deallocate after use
 *
 * History (with dates)
 * -------  ---- -----
 * 1.0.0, 30/06/1998    first release
 *
 ************************************************************************************/
static short *PerformADPCM( short inputs[ ], unsigned int nInputs, Boolean arm, Boolean encode )
{
	short	*outputs ;
	
	if( !inputs ) {
		fprintf( stderr, "[PerformADPCM] Error in input arguments, aborting.\n\n" ) ;
		/* function name given since intended as internal error for programmer */
		return NULL ;
	}
	
	if( ( outputs = ( short * )calloc( nInputs, sizeof( short ) ) ) == NULL ) {
		fprintf( stderr, "Failure to create array for output data, aborting.\n\n" ) ;
		return NULL ;
	}
	
	if( arm ) {
		printf( "ARM " ) ;
	}
	else {
		printf( "C " ) ;
	}
	if( encode ) {
		printf( "encoding PCM data...\n\n" ) ;
	}
	else {
		printf( "decoding ADPCM data...\n\n" ) ;
	}
	
	if( arm ) {
		if( !PerformADPCMARM( outputs, inputs, nInputs, encode ) ) {
			free( ( void * ) outputs ) ;
			return NULL ;
		}
	}
	else {
		if( !PerformADPCMC( outputs, inputs, nInputs, encode ) ) {
			free( ( void * ) outputs ) ;
			return NULL ;
		}
	}
	
	if( encode ) {
		printf( "PCM data encoded.\n\n" ) ;
	}
	else {
		printf( "ADPCM data decoded.\n\n" ) ;
	}

	return outputs ;
}

/**** PerformADPCMARM ***************************************************************
 *
 * Version & Date
 * -------   ----
 * 1.0.0, 30/06/1998
 *
 * Description
 * -----------
 * given an array of data values, either PCM or ADPCM, encode or decode them into
 * their corresponding ADPCM or PCM values respectively using ARM Assembler routines
 * and place the results in the given array
 *
 * Inputs
 * ------
 *   outputs
 *   - an initialised array to hold the encoded or decoded values
 *     must reference at least as many entries as input samples given
 *   inputs
 *   - an array referencing the inputs either PCM or ADPCM samples
 *   nInputs
 *   - the number of data points referenced by the array inputs
 *     also gives the number of outputs that will be produced and thus minimum size
 *     of array outputs
 *   encode
 *   - true  : values given are PCM samples and are to be encoded
 *     false : values given are ADPCM samples and are to be decoded
 * Outputs
 * -------
 *   outputs
 *   - the nInputs samples output from the function call
 *     if encode = true arary will contain ADPCM samples
 *     if encode = false array will contain PCM samples
 *     if FALSE returned, entries are undefined (see Return Values below)
 * Return Values
 * ------ ------
 *     TRUE  - the array outputs is valid and contains the required data
 *     FALSE - some error occurred, outputs does not contain valid data
 *
 * History (with dates)
 * -------  ---- -----
 * 1.0.0, 30/06/1998    first release
 *
 ************************************************************************************/
static Boolean PerformADPCMARM( short outputs[ ], short inputs[ ], unsigned int nInputs, Boolean encode )
{
	unsigned int	counter ;
	ADPCMState		state = { 0, 0 } ;
	
	if( ( !outputs ) || ( !inputs ) ) {
		fprintf( stderr, "[PerformADPCMARM] Error in input arguments, aborting.\n\n" ) ;
		/* function name given since intended as internal error for programmer */
		return FALSE ;
	}

	for( counter = 0 ; counter < nInputs ; counter += 1 ) {
		if( encode ) {
			outputs[ counter ] = ( short )adpcm_encode( ( int )inputs[ counter ], &state ) ;
			/* zero the top 4-bits, just to prove it is only 4-bits wide */
			outputs[ counter ] = ( short )( outputs[ counter ] & 0xF ) ;
		}
		else {
			outputs[ counter ] = ( short )adpcm_decode( ( int )inputs[ counter ], &state ) ;
		}
	}

	return TRUE ;
}

/**** PerformADPCMC *****************************************************************
 *
 * Version & Date
 * -------   ----
 * 1.0.0, 30/06/1998
 *
 * Description
 * -----------
 * given an array of data values, either PCM or ADPCM, encode or decode them into
 * their corresponding ADPCM or PCM values respectively using C routines
 * and place the results in the given array
 *
 * Inputs
 * ------
 *   outputs
 *   - an initialised array to hold the encoded or decoded values
 *     must reference at least as many entries as input samples given
 *   inputs
 *   - an array referencing the inputs either PCM or ADPCM samples
 *   nInputs
 *   - the number of data points referenced by the array inputs
 *     also gives the number of outputs that will be produced and thus minimum size
 *     of array outputs
 *   encode
 *   - true  : values given are PCM samples and are to be encoded
 *     false : values given are ADPCM samples and are to be decoded
 * Outputs
 * -------
 *   outputs
 *   - the nInputs samples output from the function call
 *     if encode = true arary will contain ADPCM samples
 *     if encode = false array will contain PCM samples
 *     if FALSE returned, entries are undefined (see Return Values below)
 * Return Values
 * ------ ------
 *     TRUE  - the array outputs is valid and contains the required data
 *     FALSE - some error occurred, outputs does not contain valid data
 *
 * History (with dates)
 * -------  ---- -----
 * 1.0.0, 30/06/1998    first release
 *
 ************************************************************************************/
static Boolean PerformADPCMC( short outputs[ ], short inputs[ ], unsigned int nInputs, Boolean encode )
{
	ADPCMState		state = { 0, 0 } ;
	unsigned int	counter ;
	int				previousADPCMEncoded ;
		
	if( ( !outputs ) || ( !inputs ) ) {
		fprintf( stderr, "[PerformADPCMC] Error in input arguments, aborting.\n\n" ) ;
		/* function name given since intended as internal error for programmer */
		return FALSE ;
	}

	for( counter = 0 ; counter < nInputs ; counter += 1 ) {
		if( encode ) {
			previousADPCMEncoded = 0 ;
			if( counter > 0 ) {
				previousADPCMEncoded = outputs[ counter - 1 ] ;
			}
			outputs[ counter ] = ( short )EncodeADPCMC( ( int )inputs[ counter ], previousADPCMEncoded, &state ) ;
		}
		else {
			outputs[ counter ] = ( short )DecodeADPCMC( ( int )inputs[ counter ], &state ) ;
		}
	}
	
	return TRUE ;
}

/**** Transform *********************************************************************
 *
 * Version & Date
 * -------   ----
 * 1.0.0, 30/06/1998
 *
 * Description
 * -----------
 * read a file of PCM data samples given by the user, encode them into ADPCM samples
 * using ARM or C routines, based on value of parameter, immediately decode them back
 * to PCM samples using ARM or C routines, again based on value of paramter and write
 * the new PCM values to a file given by the user
 *
 * information is also calculated including the number of bits in both the original
 * PCM data and encoded ADPCM data, percentage reduction and error information
 * between the original and new PCM samples which is written to a file given by the
 * user
 *
 * Inputs
 * ------
 *   option
 *   - a value that should be between 1 and 4 and returned from a call to NextTask
 *     the value corresponds to a menu choice and determines which of ARM or C routines
 *     are used for the encoding and decoding
 * Return Values
 * ------ ------
 *     TRUE  - the entire transformation process was successful and data written
 *     FALSE - some error occurred during process (memory problems?)
 *
 * History (with dates)
 * -------  ---- -----
 * 1.0.0, 30/06/1998    first release
 *
 ************************************************************************************/
static Boolean Transform( unsigned int option )
{
	short			*origInputs ;
	unsigned int	nInputs ;
	Boolean			armF ;
	Boolean			armI ;
	short			*outputs = NULL ;
	short			*decodedInputs = NULL ;
	unsigned int	mse ;
	unsigned int	maxAbsErr ;
	
	printf( "Perform Adaptive Differential Pulse Code Modulation...\n\n" ) ;
	
	if( ( origInputs = ( short * )GetData( HWORDBYTES, "input", &nInputs ) ) == NULL ) {
		return FALSE ;
	}
	
	switch( option ) {
		case  1 :
			armF = TRUE ;
			armI = TRUE ;
			break ;
		case  2 :
			armF = FALSE ;
			armI = FALSE ;
			break ;
		case  3 :
			armF = TRUE ;
			armI = FALSE ;
			break ;
		case  4 :
			armF = FALSE ;
			armI = TRUE ;
			break ;
		case 0 :
		default :
			free( ( void * ) origInputs ) ;
			return TRUE ;	/* don't return error, just assume ok */
	}
	
	printf( "Number of samples is '%d'\n\n", nInputs ) ;
	outputs = PerformADPCM( origInputs, nInputs, armF, TRUE ) ;
	if( !outputs ) {
		free( ( void * ) origInputs ) ;
		return FALSE ;
	}
	
	decodedInputs = PerformADPCM( outputs, nInputs, armI, FALSE ) ;
	
	free( ( void * ) outputs ) ;
	
	if( !decodedInputs ) {
		free( ( void * ) origInputs ) ;
		return FALSE ;
	}
	
	SaveData( decodedInputs, nInputs, HWORDBYTES, 0, "fully transformed" ) ;
	
	printf( "Calculating error information...\n\n" ) ;
		
	ARRAYERROR( origInputs, decodedInputs, decodedInputs, nInputs, maxAbsErr, mse, short ) ;
	printf( "Maximum absolute error value calculated as '%d'\n\n", maxAbsErr ) ;
	printf( "The mean squared error between the original and decoded PCM data is '%d'\n\n", mse ) ;

	SaveData( decodedInputs, nInputs, HWORDBYTES, 0, "error" ) ;

	free( ( void * ) origInputs ) ;
	free( ( void * ) decodedInputs ) ;
	
	return TRUE ;
}

⌨️ 快捷键说明

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