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 + -
显示快捷键?