Implement part of vorbis encoder.

This commit is contained in:
Michael Jumper 2012-10-29 11:53:08 -07:00
parent 5ea7f5589d
commit e14265ab46
2 changed files with 86 additions and 4 deletions

View File

@ -40,6 +40,27 @@
#include "audio.h" #include "audio.h"
#include <vorbis/vorbisenc.h>
typedef struct ogg_encoder_state {
/**
* Ogg state
*/
ogg_stream_state ogg_state;
ogg_page ogg_page;
ogg_packet ogg_packet;
/**
* Vorbis state
*/
vorbis_info info;
vorbis_comment comment;
vorbis_dsp_state vorbis_state;
vorbis_block vorbis_block;
} ogg_encoder_state;
extern audio_encoder* ogg_encoder; extern audio_encoder* ogg_encoder;
#endif #endif

View File

@ -35,22 +35,83 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include <stdlib.h>
#include <guacamole/client.h> #include <guacamole/client.h>
#include <guacamole/protocol.h> #include <guacamole/protocol.h>
#include <vorbis/vorbisenc.h>
#include "audio.h" #include "audio.h"
#include "ogg_encoder.h"
void ogg_encoder_begin_handler(audio_stream* audio) { void ogg_encoder_begin_handler(audio_stream* audio) {
guac_client_log_info(audio->client, /* Allocate stream state */
"OGG: Beginning audio stream."); ogg_encoder_state* state = (ogg_encoder_state*)
malloc(sizeof(ogg_encoder_state));
/* Init state */
vorbis_info_init(&(state->info));
vorbis_encode_init_vbr(&(state->info), audio->channels, audio->rate, 0.1);
vorbis_analysis_init(&(state->vorbis_state), &(state->info));
vorbis_block_init(&(state->vorbis_state), &(state->vorbis_block));
vorbis_comment_init(&(state->comment));
vorbis_comment_add_tag(&(state->comment), "ENCODER", "libguac-client-rdp");
ogg_stream_init(&(state->ogg_state), rand());
/* Write headers */
{
ogg_packet header;
ogg_packet header_comm;
ogg_packet header_code;
vorbis_analysis_headerout(
&(state->vorbis_state),
&(state->comment),
&header, &header_comm, &header_code);
ogg_stream_packetin(&(state->ogg_state), &header);
ogg_stream_packetin(&(state->ogg_state), &header_comm);
ogg_stream_packetin(&(state->ogg_state), &header_code);
/* For each packet */
while (ogg_stream_flush(&(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);
}
}
audio->data = state;
} }
void ogg_encoder_end_handler(audio_stream* audio) { void ogg_encoder_end_handler(audio_stream* audio) {
guac_client_log_info(audio->client, /* Get state */
"OGG: Ending audio stream."); ogg_encoder_state* state = (ogg_encoder_state*) audio->data;
/* Clean up encoder */
ogg_stream_clear(&(state->ogg_state));
vorbis_block_clear(&(state->vorbis_block));
vorbis_dsp_clear(&(state->vorbis_state));
vorbis_comment_clear(&(state->comment));
vorbis_info_clear(&(state->info));
/* Free stream state */
free(audio->data);
} }