Actually output sound.

This commit is contained in:
Michael Jumper 2012-10-29 12:48:33 -07:00
parent e14265ab46
commit face237d8d
2 changed files with 79 additions and 4 deletions

View File

@ -98,6 +98,9 @@ void audio_stream_end(audio_stream* audio) {
0, "audio/ogg" /* FIXME: Hard-coded mimetype */, 0, "audio/ogg" /* FIXME: Hard-coded mimetype */,
duration, audio->encoded_data, audio->encoded_data_used); duration, audio->encoded_data, audio->encoded_data_used);
/* Clear data */
audio->encoded_data_used = 0;
} }
void audio_stream_free(audio_stream* audio) { void audio_stream_free(audio_stream* audio) {

View File

@ -53,7 +53,7 @@ void ogg_encoder_begin_handler(audio_stream* audio) {
/* Init state */ /* Init state */
vorbis_info_init(&(state->info)); vorbis_info_init(&(state->info));
vorbis_encode_init_vbr(&(state->info), audio->channels, audio->rate, 0.1); vorbis_encode_init_vbr(&(state->info), audio->channels, audio->rate, 0.4);
vorbis_analysis_init(&(state->vorbis_state), &(state->info)); vorbis_analysis_init(&(state->vorbis_state), &(state->info));
vorbis_block_init(&(state->vorbis_state), &(state->vorbis_block)); vorbis_block_init(&(state->vorbis_state), &(state->vorbis_block));
@ -98,11 +98,59 @@ void ogg_encoder_begin_handler(audio_stream* audio) {
} }
void ogg_encoder_write_blocks(audio_stream* audio) {
/* Get state */
ogg_encoder_state* state = (ogg_encoder_state*) audio->data;
while (vorbis_analysis_blockout(&(state->vorbis_state),
&(state->vorbis_block)) == 1) {
/* Analyze */
vorbis_analysis(&(state->vorbis_block), NULL);
vorbis_bitrate_addblock(&(state->vorbis_block));
/* Flush Ogg pages */
while (vorbis_bitrate_flushpacket(&(state->vorbis_state),
&(state->ogg_packet))) {
/* Weld packet into bitstream */
ogg_stream_packetin(&(state->ogg_state), &(state->ogg_packet));
/* Write out pages */
while (ogg_stream_pageout(&(state->ogg_state),
&(state->ogg_page)) != 0) {
/* Write packet header */
audio_stream_write_encoded(audio,
state->ogg_page.header,
state->ogg_page.header_len);
/* Write packet body */
audio_stream_write_encoded(audio,
state->ogg_page.body,
state->ogg_page.body_len);
if (ogg_page_eos(&(state->ogg_page)))
break;
}
}
}
}
void ogg_encoder_end_handler(audio_stream* audio) { void ogg_encoder_end_handler(audio_stream* audio) {
/* Get state */ /* Get state */
ogg_encoder_state* state = (ogg_encoder_state*) audio->data; ogg_encoder_state* state = (ogg_encoder_state*) audio->data;
/* Write end-of-stream */
vorbis_analysis_wrote(&(state->vorbis_state), 0);
ogg_encoder_write_blocks(audio);
/* Clean up encoder */ /* Clean up encoder */
ogg_stream_clear(&(state->ogg_state)); ogg_stream_clear(&(state->ogg_state));
vorbis_block_clear(&(state->vorbis_block)); vorbis_block_clear(&(state->vorbis_block));
@ -118,9 +166,33 @@ void ogg_encoder_end_handler(audio_stream* audio) {
void ogg_encoder_write_handler(audio_stream* audio, void ogg_encoder_write_handler(audio_stream* audio,
unsigned char* pcm_data, int length) { unsigned char* pcm_data, int length) {
guac_client_log_info(audio->client, /* Get state */
"OGG: Writing data to stream, length=%i", ogg_encoder_state* state = (ogg_encoder_state*) audio->data;
length);
/* Calculate samples */
int samples = length / audio->channels * 8 / audio->bps;
int i;
/* Get buffer */
float** buffer = vorbis_analysis_buffer(&(state->vorbis_state), samples);
for (i=0; i<samples; i++) {
/* FIXME: For now, assume 2 channels, 16-bit */
int left = ((pcm_data[i*4+1] & 0xFF) << 8) | (pcm_data[i*4] & 0xFF);
int right = ((pcm_data[i*4+3] & 0xFF) << 8) | (pcm_data[i*4+2] & 0xFF);
/* Store sample in buffer */
buffer[0][i] = left / 32768.f;
buffer[1][i] = right / 32768.f;
}
/* Submit data */
vorbis_analysis_wrote(&(state->vorbis_state), samples);
/* Write data */
ogg_encoder_write_blocks(audio);
} }