mix.c

来自「Windows NT声卡驱动VXD」· C语言 代码 · 共 971 行 · 第 1/2 页

C
971
字号
	return 0;    }    /* mix it down */    switch ( dest_format & ESD_MASK_BITS )    {    case ESD_BITS8:	target_data_uc = (unsigned char *) dest_buf;	if ( ( dest_format & ESD_MASK_CHAN ) == ESD_MONO ) {	    /* mix mono, 8 bit sound source from mono, 8 bit */	    /* optimize for the case where all settings are the same */	    if ( dest_rate == src_rate ) {		memcpy( target_data_uc, source_data_uc, dest_len );		bytes_written = dest_len;		break;	    }	    /* scale the pointer, and copy the data */	    while ( wr_dat < dest_len )	    {		rd_dat = wr_dat * src_rate / dest_rate;		lsample = source_data_uc[ rd_dat ];		target_data_uc[ wr_dat++ ] = lsample;	    }	} else {	    /* mix stereo, 8 bit sound source from mono, 8 bit */	    while ( wr_dat < dest_len )	    {		rd_dat = wr_dat * src_rate / dest_rate;		rd_dat /= 2;		lsample = source_data_uc[ rd_dat ];		target_data_uc[ wr_dat++ ] = lsample;		target_data_uc[ wr_dat++ ] = lsample;	    }	}	bytes_written = wr_dat * sizeof(unsigned char);	break;    case ESD_BITS16:	target_data_ss = (signed short *) dest_buf;	if ( ( dest_format & ESD_MASK_CHAN ) == ESD_MONO ) {	    /* mix mono, 16 bit sound source from mono, 8 bit */	    while ( wr_dat < dest_len / sizeof(signed short) )	    {		rd_dat = wr_dat * src_rate / dest_rate;		lsample = source_data_uc[ rd_dat ] - 127;		lsample *= 256;		target_data_ss[ wr_dat++ ] = lsample;	    }	} else {	    /* mix stereo, 16 bit sound source from mono, 8 bit */	    while ( wr_dat < dest_len / sizeof(signed short) )	    {		rd_dat = wr_dat * src_rate / dest_rate;		rd_dat /= 2;		lsample = source_data_uc[ rd_dat++ ] - 127;		lsample *= 256;		target_data_ss[ wr_dat++ ] = lsample;		target_data_ss[ wr_dat++ ] = lsample;	    }	}	bytes_written = wr_dat * sizeof(signed short);	break;    default:	fprintf( stderr, "mix from 8u: format 0x%08x not supported\n", 		 dest_format & ESD_MASK_BITS );	break;    }    return bytes_written;}/*******************************************************************//* takes the input player, and mixes to 16 bit signed waveform */int mix_mono_8u_to_stereo_32s_sv( esd_player_t *player, int length ){    int rd_dat = 0;    unsigned int wr_dat=0;    signed short sample;    register unsigned char *source_data_uc 	= (unsigned char *) player->data_buffer;    ESDBG_MIXER( printf( "mixing mono 8u to stereo 32s\n" ); );    while ( wr_dat < length/sizeof(signed short) )    {	rd_dat = wr_dat * player->rate / esd_audio_rate;	rd_dat /= 2;	/* adjust for mono */		sample = source_data_uc[ rd_dat++ ];	sample -= 127; sample *= 256;		mixed_buffer[ wr_dat++ ] += sample;	mixed_buffer[ wr_dat++ ] += sample;    }        return wr_dat * sizeof(signed short);}int mix_stereo_8u_to_stereo_32s_sv( esd_player_t *player, int length ){    int rd_dat = 0;    unsigned int wr_dat=0;    signed short sample;    register unsigned char *source_data_uc 	= (unsigned char *) player->data_buffer;    ESDBG_MIXER( printf( "mixing stereo 8u to stereo 32s\n" ); );    if ( player->rate == esd_audio_rate ) {	while ( wr_dat < length/sizeof(signed short) )	{	    sample = ( source_data_uc[ wr_dat ] - 127 ) * 256;	    mixed_buffer[ wr_dat ] += sample;	    wr_dat++;	}    } else {	while ( wr_dat < length/sizeof(signed short) )	{	    rd_dat = wr_dat * player->rate / esd_audio_rate;	    	    sample = source_data_uc[ rd_dat++ ];	    sample -= 127; sample *= 256;	    	    mixed_buffer[ wr_dat++ ] += sample;	}    }        return wr_dat * sizeof(signed short);}    int mix_mono_16s_to_stereo_32s_sv( esd_player_t *player, int length ){    int rd_dat = 0;    unsigned int wr_dat=0;    signed short sample;    register signed short *source_data_ss	= (signed short *) player->data_buffer;    ESDBG_MIXER( printf( "mixing mono 16s to stereo 32s\n" ); );    /* mix mono, 16 bit sound source to stereo, 16 bit */    while ( wr_dat < length/sizeof(signed short) )    {	rd_dat = wr_dat * player->rate / esd_audio_rate;	rd_dat /= 2;	/* adjust for mono */		sample = source_data_ss[ rd_dat++ ];		mixed_buffer[ wr_dat++ ] += sample;	mixed_buffer[ wr_dat++ ] += sample;    }    return wr_dat * sizeof(signed short);}	int mix_stereo_16s_to_stereo_32s_sv( esd_player_t *player, int length ){    int rd_dat = 0;    unsigned int wr_dat=0;    signed short sample;    register signed short *source_data_ss	= (signed short *) player->data_buffer;    ESDBG_MIXER( printf( "mixing stereo 16s to stereo 32s\n" ); );    if ( player->rate == esd_audio_rate ) {	/* optimize for simple increment by one and add loop */	while ( wr_dat < length/sizeof(signed short) )	{	    mixed_buffer[ wr_dat ] += source_data_ss[ wr_dat ];	    wr_dat++;	}    } else {	/* non integral multiple of sample rates, do it the hard way */	while ( wr_dat < length/sizeof(signed short) )	{	    rd_dat = wr_dat * player->rate / esd_audio_rate;	    sample = source_data_ss[ rd_dat++ ];	    mixed_buffer[ wr_dat++ ] += sample;	}    }     return wr_dat * sizeof(signed short);}/*******************************************************************//* take input player, mix to 16 bit signed waveform, volume control */int mix_mono_8u_to_stereo_32s( esd_player_t *player, int length ){    int rd_dat = 0;    unsigned int wr_dat=0;    signed short sample;    register unsigned char *source_data_uc 	= (unsigned char *) player->data_buffer;    ESDBG_MIXER( printf( "mixing mono 8u to stereo 32s\n" ); );    while ( wr_dat < length/sizeof(signed short) )    {	rd_dat = wr_dat * player->rate / esd_audio_rate;	rd_dat /= 2;	/* adjust for mono */		sample = source_data_uc[ rd_dat++ ];	sample -= 127; sample *= 256;		sample = sample * player->left_vol_scale / ESD_VOLUME_BASE;	sample = sample * player->right_vol_scale / ESD_VOLUME_BASE;	mixed_buffer[ wr_dat++ ] += sample;	mixed_buffer[ wr_dat++ ] += sample;    }        return wr_dat * sizeof(signed short);}int mix_stereo_8u_to_stereo_32s( esd_player_t *player, int length ){    int rd_dat = 0;    unsigned int wr_dat=0;    signed short sample;    register unsigned char *source_data_uc 	= (unsigned char *) player->data_buffer;    ESDBG_MIXER( printf( "mixing stereo 8u to stereo 32s\n" ); );    if ( player->rate == esd_audio_rate ) {	while ( wr_dat < length/sizeof(signed short) )	{	    sample = ( source_data_uc[ wr_dat ] - 127 ) * 256;	    sample = sample * player->left_vol_scale / ESD_VOLUME_BASE;	    mixed_buffer[ wr_dat++ ] += sample;	    sample = ( source_data_uc[ wr_dat ] - 127 ) * 256;	    sample = sample * player->right_vol_scale / ESD_VOLUME_BASE;	    mixed_buffer[ wr_dat++ ] += sample;	}    } else {	while ( wr_dat < length/sizeof(signed short) )	{	    rd_dat = wr_dat * player->rate / esd_audio_rate;	    if ( rd_dat % 2 ) rd_dat++;	    sample = source_data_uc[ rd_dat++ ];	    sample -= 127; sample *= 256;	    sample = sample * player->left_vol_scale / ESD_VOLUME_BASE;	    mixed_buffer[ wr_dat++ ] += sample;	    sample = source_data_uc[ rd_dat++ ];	    sample -= 127; sample *= 256;	    sample = sample * player->right_vol_scale / ESD_VOLUME_BASE;	    mixed_buffer[ wr_dat++ ] += sample;	}    }        return wr_dat * sizeof(signed short);}    int mix_mono_16s_to_stereo_32s( esd_player_t *player, int length ){    int rd_dat = 0;    unsigned int wr_dat=0;    signed short sample;    register signed short *source_data_ss	= (signed short *) player->data_buffer;    ESDBG_MIXER( printf( "mixing mono 16s to stereo 32s\n" ); );    /* mix mono, 16 bit sound source to stereo, 16 bit */    while ( wr_dat < length/sizeof(signed short) )    {	rd_dat = wr_dat * player->rate / esd_audio_rate;	rd_dat /= 2;	/* adjust for mono */		sample = source_data_ss[ rd_dat++ ];		mixed_buffer[ wr_dat++ ] 	    += sample * player->left_vol_scale / ESD_VOLUME_BASE;	mixed_buffer[ wr_dat++ ] 	    += sample * player->right_vol_scale / ESD_VOLUME_BASE;    }    return wr_dat * sizeof(signed short);}	int mix_stereo_16s_to_stereo_32s( esd_player_t *player, int length ){    int rd_dat = 0;    unsigned int wr_dat=0;    signed short sample;    register signed short *source_data_ss	= (signed short *) player->data_buffer;    ESDBG_MIXER( printf( "mixing stereo 16s to stereo 32s\n" ); );    if ( player->rate == esd_audio_rate ) {	/* optimize for simple increment by one and add loop */	while ( wr_dat < length/sizeof(signed short) )	{	    sample = source_data_ss[ wr_dat ];	    sample = sample * player->left_vol_scale / ESD_VOLUME_BASE;	    mixed_buffer[ wr_dat++ ] += sample;	    sample = source_data_ss[ wr_dat ];	    sample = sample * player->right_vol_scale / ESD_VOLUME_BASE;	    mixed_buffer[ wr_dat++ ] += sample;	}    } else {	/* non integral multiple of sample rates, do it the hard way */	while ( wr_dat < length/sizeof(signed short) )	{	    rd_dat = wr_dat * player->rate / esd_audio_rate;	    if ( rd_dat % 2 ) rd_dat++;	    sample = source_data_ss[ rd_dat++ ];	    sample = sample * player->left_vol_scale / ESD_VOLUME_BASE;	    mixed_buffer[ wr_dat++ ] += sample;	    sample = source_data_ss[ rd_dat++ ];	    sample = sample * player->right_vol_scale / ESD_VOLUME_BASE;	    mixed_buffer[ wr_dat++ ] += sample;	}    }     return wr_dat * sizeof(signed short);}/*******************************************************************//* takes mixed data, and clips data to the output buffer */void clip_mix_to_output_16s( signed short *output, int length ){    signed int *mixed = mixed_buffer;    signed int *end = mixed_buffer + length/sizeof(signed short);    ESDBG_MIXER( printf( "clipping mix to output 16 bit (%d bytes)\n",			 length ); );    while ( mixed != end ) {	if (*mixed < SHRT_MIN) {	    *output++ = SHRT_MIN; mixed++;	} else if (*mixed > SHRT_MAX) {	    *output++ = SHRT_MAX; mixed++;	} else {	    *output++ = *mixed++;	}    }}/*******************************************************************//* takes mixed data, and clips data to the output buffer */void clip_mix_to_output_8u( signed char *output, int length ){    signed int *mixed = mixed_buffer;    signed int *end = mixed_buffer + length/sizeof(signed short);    ESDBG_MIXER( printf( "clipping mix to output 8 bit (%d bytes)\n", 			 length ); );    while ( mixed != end ) {	if (*mixed < SHRT_MIN) {	    *output++ = 0; mixed++;	} else if (*mixed > SHRT_MAX) {	    *output++ = 255; mixed++;	} else {	    *output++ = (*mixed++) / 256 + 128;	}    }}/*******************************************************************//* takes all input players, and mixes them to the mixed_buffer */int mix_players( void *output, int length ){    int actual = 0, max = 0;    esd_player_t *player = NULL;    esd_player_t *erase = NULL;    ESDBG_MIXER( printf( "++++++++++++++++++++++++++++++++++++++++++\n" ); );    /* zero the sum buffer */    memset( mixed_buffer, 0, esd_buf_size_samples * sizeof(int) );        /* as long as there's a player out there */    player = esd_players_list;    while( player != NULL )    {	/* read the client sound data */	actual = read_player( player );	/* read_player(): >0 = data, ==0 = no data, <0 = erase it */	if ( actual > 0  ) {	    /* printf( "received: %d bytes from %d\n", 	            actual, player->source_id ); */	    /* actual = mix_to_stereo_32s( player, length ); */	    actual = player->mix_func( player, length );	    if ( actual > max ) max = actual;	    	} else if ( actual == 0 ) {	    ESDBG_TRACE( printf( "(%02d) no data available from player [%p]\n", 				 player->source_id, player ); );	} else {	    /* actual < 0 means erase the player */	    erase = player;	}	/* check out the next item in the list */	player = player->next;	/* clean up any fished players */	if ( erase != NULL ) {	    erase_player( erase );	    erase = NULL;	}    }    /* ESDBG_COMMS( printf( "maximum stream length = %d bytes\n", max ); ); */     if ( (esd_audio_format & ESD_MASK_BITS) == ESD_BITS16 ) 	clip_mix_to_output_16s( output, max );    else {	clip_mix_to_output_8u( output, max );	max /= 2; /* half as many samples as you'd think */    }    return max;}int refresh_mix_funcs(){    esd_player_t *filter = esd_filter_list;    int translations = 0;    /* walk the filters lists, and refresh the translate functions */    ESDBG_MIXER( printf( "refreshing mix functions\n" ); );        /* see if we need any translate functions */    if ( !esd_filter_list ) 	return 0;    /* set the translation into the first filter */    esd_first_filter_func = get_translate_func( esd_audio_format, 						esd_audio_rate, 						esd_filter_list->format, 						esd_filter_list->rate );    translations++;    while ( filter ) {	if ( filter->next ) {	    filter->translate_func		= get_translate_func( filter->format, filter->rate, 				      filter->next->format, 				      filter->next->rate );	} else {	    filter->translate_func 		= get_translate_func( filter->format, filter->rate, 				      esd_audio_format, 				      esd_audio_rate );	}	filter = filter->next;	translations++;    }        return translations;}

⌨️ 快捷键说明

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