players.c

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

C
581
字号
	    return -1;	}	/* copy the data from the sample to the player */	actual = ( ((esd_sample_t*)player->parent)->sample_length 		   - player->last_pos > player->buffer_length )	    ? player->buffer_length 	    : ((esd_sample_t*)player->parent)->sample_length - player->last_pos;	if ( actual > 0 ) {	    memcpy( player->data_buffer, 		    ((esd_sample_t*)player->parent)->data_buffer 		    + player->last_pos, actual );	    player->last_pos += actual;	    if ( ( player->format & ESD_MASK_FUNC ) != ESD_LOOP ) {		/* we're done for this iteration */		break;	    }	} else {	    /* something horrible has happened to the sample */	    return -1;	}	/* we are looping, see if we need to copy another block */	if ( player->last_pos >= ((esd_sample_t*)player->parent)->sample_length ) {	    player->last_pos = 0;	}	actual_2nd = ( ((esd_sample_t*)player->parent)->sample_length 		   - player->last_pos > player->buffer_length - actual )	    ? player->buffer_length - actual	    : ((esd_sample_t*)player->parent)->sample_length - player->last_pos;	if ( actual_2nd >= 0 ) {	    /* only keep going if we didn't want to stop looping */	    if ( ( ((esd_sample_t*)player->parent)->format & ESD_MASK_FUNC )		 != ESD_STOP ) {		memcpy( player->data_buffer + actual, 			((esd_sample_t*)player->parent)->data_buffer 			+ player->last_pos, actual_2nd );		player->last_pos += actual_2nd;		actual += actual_2nd;		/* make sure we're not at the end */		if ( player->last_pos >= ((esd_sample_t*)player->parent)->sample_length ) {		    player->last_pos = 0;		}	    }	} else {	    /* something horrible has happened to the sample */	    return -1;	}	/* sample data is swapped as it's cached, no swap needed here */	break;    default:	ESDBG_TRACE( printf( "-%02d- read_player: format 0x%08x not supported\n", 			     player->source_id, player->format ); );	return -1;    }    return actual;}/*******************************************************************//* send the players buffer to it's associated socket, erase if EOF */void monitor_write( void *output_buffer, int length ) {    fd_set wr_fds;    int can_write;    struct timeval timeout;    esd_player_t *monitor, *remove = NULL;    /* make sure we have a monitor connected */    if ( !esd_monitor_list ) 	return;    /* shuffle through the list of monitors */    monitor = esd_monitor_list;    while ( monitor != NULL ) {	/* see if we can write to the socket */	timeout.tv_sec = 0;	timeout.tv_usec = 0;	FD_ZERO( &wr_fds );	FD_SET( monitor->source_id, &wr_fds );	can_write = select( monitor->source_id + 1, NULL, &wr_fds, NULL, &timeout );	if ( !can_write ) 	    break;	/* mix down the monitor's buffer */	length = monitor->translate_func( monitor->data_buffer, 					  monitor->buffer_length,					  monitor->rate, 					  monitor->format, 					  output_buffer, 					  length, 					  esd_audio_rate,					  esd_audio_format );	/* write the data buffer to the socket */	ESD_WRITE_BIN( monitor->source_id, monitor->data_buffer, 		       monitor->buffer_length, length, "mon wr" );	if ( length < 0 ) {	    /* error on write, close it down */	    ESDBG_TRACE( printf( "(%02d) closing monitor\n", monitor->source_id ); );	    remove = monitor;	}	monitor = monitor->next;	if ( remove ) {	    erase_client( remove->parent );	    erase_monitor( remove );	    remove = NULL;	}    }        return;}int recorder_write( void *buffer, int length ) {    /* write it out */    ESDBG_TRACE( printf( "(%02d) writing recorder data\n", 			 esd_recorder->source_id ); );    length = write_player( esd_recorder, buffer,  length, 			   esd_audio_rate, esd_audio_format);    /* see how it went */    if ( length < 0 ) {	/* couldn't send anything, close it down */	ESDBG_TRACE( printf( "(%02d) closing recorder\n", 			     esd_recorder->source_id ); );	/* stop recording */	esd_audio_close();	esd_audio_format &= ~ESD_RECORD;	esd_audio_open();	/* clear the recorder */	erase_client( esd_recorder->parent );	free_player( esd_recorder );	esd_recorder = NULL;    }    return length;}/*******************************************************************//* allocate and initialize a player from client stream */esd_player_t *new_stream_player( esd_client_t *client ){    esd_player_t *player;    /* make sure we have the memory to save the client... */    player = (esd_player_t*) malloc( sizeof(esd_player_t) );    if ( player == NULL ) {	return NULL;    }        /* and initialize the player */    player->next = NULL;    player->parent = NULL;    player->format = *(int*)(client->proto_data);    player->rate = *(int*)(client->proto_data + sizeof(int));    player->format = maybe_swap_32( client->swap_byte_order, player->format );    player->format &= ~ESD_MASK_MODE; /* force to ESD_STREAM */    player->rate = maybe_swap_32( client->swap_byte_order, player->rate );    player->source_id = client->fd;    strncpy( player->name, client->proto_data + 2 * sizeof(int), ESD_NAME_MAX );    player->name[ ESD_NAME_MAX - 1 ] = '\0';    ESDBG_TRACE( printf( "(%02d) stream %s: 0x%08x at %d Hz\n", client ->fd, 			 player->name, player->format, player->rate ); );    /* Reduce buffers on sockets to the minimum needed */    esd_set_socket_buffers( player->source_id, player->format, 			    player->rate, esd_audio_rate );    /* calculate buffer length to match the mix buffer duration */    player->buffer_length = esd_buf_size_octets * player->rate / esd_audio_rate;    if ( (player->format & ESD_MASK_BITS) == ESD_BITS8 )	player->buffer_length /= 2;    if ( (player->format & ESD_MASK_CHAN) == ESD_MONO )	player->buffer_length /= 2;    /* force to an even multiple of 4 */    player->buffer_length += ( 4 - (player->buffer_length % 4) ) % 4;    player->data_buffer	= (void *) malloc( player->buffer_length );    /* if not enough room for data buffer, clean up, and return NULL */    if ( player->data_buffer == NULL ) {	free( player );	return NULL;    }    /* everything's ok, set the easy stuff */    player->left_vol_scale = player->right_vol_scale = ESD_VOLUME_BASE;    player->mix_func = get_mix_func( player );    player->translate_func = NULL; /* no translating, just mixing */    ESDBG_TRACE( printf( "(%02d) player: [%p]\n", player->source_id, player ); );    return player;}/*******************************************************************//* allocate and initialize a player from client stream */esd_player_t *new_sample_player( int sample_id, int loop ){    esd_player_t *player;    esd_sample_t *sample;    /* find the sample we want to play */    for ( sample = esd_samples_list ; sample != NULL 	      ; sample = sample->next )    {	if ( sample->sample_id == sample_id ) {	    break;	}    }    /* if we didn't find it, return NULL */    if ( sample == NULL ) {	return NULL;    }            /* make sure we have the memory to save the player... */    player = (esd_player_t*) malloc( sizeof(esd_player_t) );    if ( player == NULL ) {	return NULL;    }        /* and initialize the player */    player->next = NULL;    player->parent = sample;    player->format = sample->format & ~ESD_MASK_MODE;    player->format |= ESD_SAMPLE;    if ( loop ) {	player->format &= ~ESD_MASK_FUNC;	player->format |= ESD_LOOP;    }    player->rate = sample->rate;    player->source_id = sample->sample_id;    player->left_vol_scale = sample->left_vol_scale;    player->right_vol_scale = sample->right_vol_scale;    ESDBG_TRACE( printf( "<%02d> connection format: 0x%08x at %d Hz\n", 			 player->source_id, player->format, player->rate ); );    /* calculate buffer length to match the mix buffer duration */    player->buffer_length = esd_buf_size_octets * player->rate / esd_audio_rate;    if ( (player->format & ESD_MASK_BITS) == ESD_BITS8 )	player->buffer_length /= 2;    if ( (player->format & ESD_MASK_CHAN) == ESD_MONO )	player->buffer_length /= 2;    /* force to an even multiple of 4 */    player->buffer_length += ( 4 - (player->buffer_length % 4) ) % 4;    player->data_buffer	= (void *) malloc( player->buffer_length );    /* if not enough room for data buffer, clean up, and return NULL */    if ( player->data_buffer == NULL ) {	free( player );	return NULL;    }    /* update housekeeping values */    esd_playing_samples++;    player->last_pos = 0;    sample->ref_count++;    player->mix_func = get_mix_func( player );    player->translate_func = NULL; /* no translating, just mixing */    ESDBG_TRACE( printf( "<%02d> new player: refs=%d samps=%d [%p]\n", 			 player->source_id, sample->ref_count, 			 esd_playing_samples, player ); );    /* everything's ok, return the allocated player */    return player;}

⌨️ 快捷键说明

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