static void init_audio(nestegg *ctx, int track, audio_context *audio_ctx, int volume) { // read vorbis header and initialize vorbis decoding unsigned chunk, chunks; vorbis_init(&(audio_ctx->vorbis_ctx)); nestegg_track_codec_data_count(ctx, track, &chunks); assert(chunks == 3); for (chunk=0; chunk<chunks; chunk++) { unsigned char *data; size_t data_size; nestegg_track_codec_data(ctx, track, chunk, &data, &data_size); vorbis_headerpacket(&(audio_ctx->vorbis_ctx), data, data_size, chunk); } // initialize audio decoding context vorbis_prepare(&(audio_ctx->vorbis_ctx)); nestegg_audio_params audioParams; nestegg_track_audio_params(ctx, track, &audioParams); audio_ctx->vorbis_ctx.channels = audioParams.channels; audio_ctx->frequency = (int)audioParams.rate; audio_ctx->avail_samples = audio_ctx->last_samples = 0; audio_ctx->packet_queue = queue_init(PACKET_QUEUE_SIZE); printf("Audio track: %f Hz, %d channels, %d bits/sample\n", audioParams.rate, audioParams.channels, audioParams.depth / audioParams.channels); if(audio_ctx->frequency % 11025) { printf("Warning: the audio frequency (%i Hz) is suboptimal; resample to 44100 Hz for best quality\n", audio_ctx->frequency); } // initialize soundmix music channel sound_close_music(); memset(&musicchannel, 0, sizeof(musicchannel)); musicchannel.fp_period = INT_TO_FIX(audio_ctx->frequency) / playfrequency; musicchannel.volume[0] = volume; musicchannel.volume[1] = volume; musicchannel.channels = audioParams.channels; musicchannel.active = 1; int i; for(i = 0; i < MUSIC_NUM_BUFFERS; i++) { musicchannel.buf[i] = malloc(MUSIC_BUF_SIZE * sizeof(short)); memset(musicchannel.buf[i], 0, MUSIC_BUF_SIZE * sizeof(short)); } }
static gint vorbis_open(void) { ogg_packet header; ogg_packet header_comm; ogg_packet header_code; vorbis_init(NULL); vorbis_info_init(&vi); vorbis_comment_init(&vc); if (tuple) { gchar tmpstr[32]; gint scrint; add_string_from_tuple (& vc, "title", tuple, FIELD_TITLE); add_string_from_tuple (& vc, "artist", tuple, FIELD_ARTIST); add_string_from_tuple (& vc, "album", tuple, FIELD_ALBUM); add_string_from_tuple (& vc, "genre", tuple, FIELD_GENRE); add_string_from_tuple (& vc, "date", tuple, FIELD_DATE); add_string_from_tuple (& vc, "comment", tuple, FIELD_COMMENT); if ((scrint = tuple_get_int(tuple, FIELD_TRACK_NUMBER, NULL))) { g_snprintf(tmpstr, sizeof(tmpstr), "%d", scrint); vorbis_comment_add_tag(&vc, "tracknumber", tmpstr); } if ((scrint = tuple_get_int(tuple, FIELD_YEAR, NULL))) { g_snprintf(tmpstr, sizeof(tmpstr), "%d", scrint); vorbis_comment_add_tag(&vc, "year", tmpstr); } } if (vorbis_encode_init_vbr (& vi, input.channels, input.frequency, v_base_quality)) { vorbis_info_clear(&vi); return 0; } vorbis_analysis_init(&vd, &vi); vorbis_block_init(&vd, &vb); srand(time(NULL)); ogg_stream_init(&os, rand()); vorbis_analysis_headerout(&vd, &vc, &header, &header_comm, &header_code); ogg_stream_packetin(&os, &header); ogg_stream_packetin(&os, &header_comm); ogg_stream_packetin(&os, &header_code); while (ogg_stream_flush (& os, & og)) { write_output(og.header, og.header_len); write_output(og.body, og.body_len); } return 1; }