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