Пример #1
0
void OggOpusFile::WriteHeader()
{  
    /*The Identification Header is 19 bytes, plus a Channel Mapping Table for
    mapping families other than 0. The Channel Mapping Table is 2 bytes +
    1 byte per channel. Because the maximum number of channels is 255, the
    maximum size of this header is 19 + 2 + 255 = 276 bytes.*/
    unsigned char header_data[276];
    const char         *opus_version;
    opus_version=opus_get_version_string();
    comment_init(&inopt.comments, &inopt.comments_length, opus_version);
//    snprintf(ENCODER_string, sizeof(ENCODER_string), "opusenc from %s %s",PACKAGE_NAME,"1.5");
    CStdString encode_string;
    encode_string.Format("opusenc from %s 1.5", PACKAGE_NAME);
    strcpy(ENCODER_string, encode_string.c_str());
    comment_add(&inopt.comments, &inopt.comments_length, "ENCODER", ENCODER_string);

    int packet_size=opus_header_to_packet(&header, header_data, sizeof(header_data));
    op.packet=header_data;
    op.bytes=packet_size;
    op.b_o_s=1;
    op.e_o_s=0;
    op.granulepos=0;
    op.packetno=0;
    ogg_stream_packetin(&os, &op);

    while((ret=ogg_stream_flush(&os, &og))){
        if(!ret)break;
        
        ret=oe_write_page(&og);
        if(ret!=og.header_len+og.body_len){
            fprintf(stderr,"Error: failed writing header to output stream\n");
            exit(1);
        }
        bytes_written+=ret;
        pages_out++;
    }

    comment_pad(&inopt.comments, &inopt.comments_length, comment_padding);
    op.packet=(unsigned char *)inopt.comments;
    op.bytes=inopt.comments_length;
    op.b_o_s=0;
    op.e_o_s=0;
    op.granulepos=0;
    op.packetno=1;
    ogg_stream_packetin(&os, &op);
    
    /* writing the rest of the Opus header packets */
    while((ret=ogg_stream_flush(&os, &og))){
        if(!ret)break;
        ret=oe_write_page(&og);
        if(ret!=og.header_len + og.body_len){
            fprintf(stderr,"Error: failed writing header to output stream\n");
            exit(1);
        }
            bytes_written+=ret;
            pages_out++;
    }    
}
Пример #2
0
int opus_enc_init(opus_enc *opus)
{
    int err;

	err = 0;
	opus->header = (OpusHeader *)calloc(1, sizeof(OpusHeader));
	opus->header_data = (unsigned char *)calloc (1, 1024);	
	opus->tags = (unsigned char *)calloc (1, 1024);
	opus->buffer = (unsigned char *)calloc (1, 4 * 4096);
    srand(time(NULL));
    ogg_stream_init(&opus->os, rand());
	opus->header->gain = 0;
	opus->header->channels = opus->channel;
	
	if ((opus->bitrate < 8000) || (opus->bitrate > 320000)) {
		opus->bitrate = DEFAULT_OPUS_BITRATE;
	}

	opus->header->input_sample_rate = 48000;
	opus->encoder = opus_encoder_create (opus->header->input_sample_rate, opus->channel, OPUS_APPLICATION_AUDIO, &err);
	opus_encoder_ctl (opus->encoder, OPUS_SET_BITRATE(opus->bitrate));
	if (opus->encoder == NULL) {
		printf("Opus Encoder creation error: %s\n", opus_strerror (err));
		return 1;
	}
	opus->last_bitrate = opus->bitrate;
	opus_encoder_ctl (opus->encoder, OPUS_GET_LOOKAHEAD (&opus->header->preskip));
	opus->header_size = opus_header_to_packet (opus->header, opus->header_data, 100);

	opus->tags_size = 
	8 + 4 + strlen (opus_get_version_string ()) + 4 + 4 + strlen ("ENCODER=") + strlen (VERSION);
	
	memcpy (opus->tags, "OpusTags", 8);
	
	opus->tags[8] = strlen (opus_get_version_string ());
	
	memcpy (opus->tags + 12, opus_get_version_string (), strlen (opus_get_version_string ()));

	opus->tags[12 + strlen (opus_get_version_string ())] = 1;

	opus->tags[12 + strlen (opus_get_version_string ()) + 4] = strlen ("ENCODER=") + strlen (VERSION);
	
	memcpy (opus->tags + 12 + strlen (opus_get_version_string ()) + 4 + 4, "ENCODER=", strlen ("ENCODER="));
	
	memcpy (opus->tags + 12 + strlen (opus_get_version_string ()) + 4 + 4 + strlen ("ENCODER="),
			VERSION,
			strlen (VERSION));	

	//printf("Opus Encoder Created\n");

    return 0;
}
Пример #3
0
int opus_write_header(uint8_t **p_extra, int *i_extra, OpusHeader *header)
{
    unsigned char header_data[100];
    const int packet_size = opus_header_to_packet(header, header_data,
                                                  sizeof(header_data));
    ogg_packet headers[2];
    headers[0].packet = header_data;
    headers[0].bytes = packet_size;
    headers[0].b_o_s = 1;
    headers[0].e_o_s = 0;
    headers[0].granulepos = 0;
    headers[0].packetno = 0;

    size_t comments_length;
    char *comments = comment_init(&comments_length);
    if (!comments)
        return 1;
    if (comment_add(&comments, &comments_length, "ENCODER=",
                    "VLC media player"))
    {
        free(comments);
        return 1;
    }

    if (comment_pad(&comments, &comments_length))
    {
        free(comments);
        return 1;
    }

    headers[1].packet = (unsigned char *) comments;
    headers[1].bytes = comments_length;
    headers[1].b_o_s = 0;
    headers[1].e_o_s = 0;
    headers[1].granulepos = 0;
    headers[1].packetno = 1;

    for (unsigned i = 0; i < ARRAY_SIZE(headers); ++i)
    {
        if (xiph_AppendHeaders(i_extra, (void **) p_extra,
                               headers[i].bytes, headers[i].packet))
        {
            *i_extra = 0;
            *p_extra = NULL;
        }
    }

    return 0;
}
Пример #4
0
bool OpusFile::Open(const ACE_TString& filename,
                    int channels, int samplerate,
                    int framesize)
{

    if(!m_ogg.Open('S') || !m_oggfile.Open(filename))
    {
        Close();
        return false;
    }

    m_samplerate = samplerate;
    m_frame_size = framesize;
    OpusHeader header = {};
    header.preskip = 0;
    header.channels = channels;
    header.channel_mapping = 0;
    header.input_sample_rate = samplerate;
    header.gain = 0;
    header.nb_streams = 1;
    header.nb_coupled = channels == 2? 1 : 0;

    unsigned char header_data[276];
    int packet_size = opus_header_to_packet(&header, header_data, sizeof(header_data));
    ogg_packet op;
    op.packet = header_data;
    op.bytes = packet_size;
    op.b_o_s = 1;
    op.e_o_s = 0;
    op.granulepos = 0;
    op.packetno = 0;

    m_ogg.PutPacket(op);

    ogg_page og;
    int ret;
    while((ret = m_ogg.FlushPageOut(og))>0)
    {
        m_oggfile.WriteOggPage(og);
    }
    m_packet_no = 2;
    return ret >= 0;
}
Пример #5
0
int opus_write_header(uint8_t **p_extra, int *i_extra, OpusHeader *header, const char *vendor)
{
    unsigned char header_data[100];
    const int packet_size = opus_header_to_packet(header, header_data,
                                                  sizeof(header_data));

    unsigned char *data[2];
    size_t size[2];

    data[0] = header_data;
    size[0] = packet_size;

    size_t comments_length;
    char *comments = comment_init(&comments_length, vendor);
    if (!comments)
        return 1;
    if (comment_add(&comments, &comments_length, "ENCODER=",
                    "VLC media player"))
    {
        free(comments);
        return 1;
    }

    if (comment_pad(&comments, &comments_length))
    {
        free(comments);
        return 1;
    }

    data[1] = (unsigned char *) comments;
    size[1] = comments_length;

    for (unsigned i = 0; i < ARRAY_SIZE(data); ++i)
        if (xiph_AppendHeaders(i_extra, (void **) p_extra, size[i], data[i]))
        {
            *i_extra = 0;
            *p_extra = NULL;
        }

    return 0;
}
Пример #6
0
int initRecorder(const char *path) {
    cleanupRecorder();

    if (!path) {
        return 0;
    }

    _fileOs = fopen(path, "wb");
    if (!_fileOs) {
        return 0;
    }

    inopt.rate = rate;
    inopt.gain = 0;
    inopt.endianness = 0;
    inopt.copy_comments = 0;
    inopt.rawmode = 1;
    inopt.ignorelength = 1;
    inopt.samplesize = 16;
    inopt.channels = 1;
    inopt.skip = 0;

    comment_init(&inopt.comments, &inopt.comments_length, opus_get_version_string());

    if (rate > 24000) {
        coding_rate = 48000;
    } else if (rate > 16000) {
        coding_rate = 24000;
    } else if (rate > 12000) {
        coding_rate = 16000;
    } else if (rate > 8000) {
        coding_rate = 12000;
    } else {
        coding_rate = 8000;
    }

    if (rate != coding_rate) {
        LOGE("Invalid rate");
        return 0;
    }

    header.channels = 1;
    header.channel_mapping = 0;
    header.input_sample_rate = rate;
    header.gain = inopt.gain;
    header.nb_streams = 1;

    int result = OPUS_OK;
    _encoder = opus_encoder_create(coding_rate, 1, OPUS_APPLICATION_AUDIO, &result);
    if (result != OPUS_OK) {
        LOGE("Error cannot create encoder: %s", opus_strerror(result));
        return 0;
    }

    min_bytes = max_frame_bytes = (1275 * 3 + 7) * header.nb_streams;
    _packet = malloc(max_frame_bytes);

    result = opus_encoder_ctl(_encoder, OPUS_SET_BITRATE(bitrate));
    if (result != OPUS_OK) {
        LOGE("Error OPUS_SET_BITRATE returned: %s", opus_strerror(result));
        return 0;
    }

#ifdef OPUS_SET_LSB_DEPTH
    result = opus_encoder_ctl(_encoder, OPUS_SET_LSB_DEPTH(max(8, min(24, inopt.samplesize))));
    if (result != OPUS_OK) {
        LOGE("Warning OPUS_SET_LSB_DEPTH returned: %s", opus_strerror(result));
    }
#endif

    opus_int32 lookahead;
    result = opus_encoder_ctl(_encoder, OPUS_GET_LOOKAHEAD(&lookahead));
    if (result != OPUS_OK) {
        LOGE("Error OPUS_GET_LOOKAHEAD returned: %s", opus_strerror(result));
        return 0;
    }

    inopt.skip += lookahead;
    header.preskip = (int)(inopt.skip * (48000.0 / coding_rate));
    inopt.extraout = (int)(header.preskip * (rate / 48000.0));

    if (ogg_stream_init(&os, rand()) == -1) {
        LOGE("Error: stream init failed");
        return 0;
    }

    unsigned char header_data[100];
    int packet_size = opus_header_to_packet(&header, header_data, 100);
    op.packet = header_data;
    op.bytes = packet_size;
    op.b_o_s = 1;
    op.e_o_s = 0;
    op.granulepos = 0;
    op.packetno = 0;
    ogg_stream_packetin(&os, &op);

    while ((result = ogg_stream_flush(&os, &og))) {
        if (!result) {
            break;
        }

        int pageBytesWritten = writeOggPage(&og, _fileOs);
        if (pageBytesWritten != og.header_len + og.body_len) {
            LOGE("Error: failed writing header to output stream");
            return 0;
        }
        bytes_written += pageBytesWritten;
        pages_out++;
    }

    comment_pad(&inopt.comments, &inopt.comments_length, comment_padding);
    op.packet = (unsigned char *)inopt.comments;
    op.bytes = inopt.comments_length;
    op.b_o_s = 0;
    op.e_o_s = 0;
    op.granulepos = 0;
    op.packetno = 1;
    ogg_stream_packetin(&os, &op);

    while ((result = ogg_stream_flush(&os, &og))) {
        if (result == 0) {
            break;
        }

        int writtenPageBytes = writeOggPage(&og, _fileOs);
        if (writtenPageBytes != og.header_len + og.body_len) {
            LOGE("Error: failed writing header to output stream");
            return 0;
        }

        bytes_written += writtenPageBytes;
        pages_out++;
    }

    free(inopt.comments);

    return 1;
}
Пример #7
0
krad_opus_t *krad_opus_encoder_create (int channels, int input_sample_rate, int bitrate, int application) {

	int c;

	krad_opus_t *krad_opus = calloc(1, sizeof(krad_opus_t));

	krad_opus->opus_header = calloc(1, sizeof(OpusHeader));

	krad_opus->input_sample_rate = input_sample_rate;
	krad_opus->channels = channels;
	krad_opus->bitrate = bitrate;
	krad_opus->application = application;
	krad_opus->complexity = DEFAULT_OPUS_COMPLEXITY;
	krad_opus->signal = OPUS_AUTO;
	krad_opus->frame_size = DEFAULT_OPUS_FRAME_SIZE;
	krad_opus->bandwidth = OPUS_BANDWIDTH_FULLBAND;

	krad_opus->new_frame_size = krad_opus->frame_size;
	krad_opus->new_complexity = krad_opus->complexity;
	krad_opus->new_bitrate = krad_opus->bitrate;
	krad_opus->new_signal = krad_opus->signal;
	krad_opus->new_bandwidth = krad_opus->bandwidth;
	
	for (c = 0; c < krad_opus->channels; c++) {
		krad_opus->ringbuf[c] = krad_ringbuffer_create (RINGBUFFER_SIZE);
		krad_opus->resampled_ringbuf[c] = krad_ringbuffer_create (RINGBUFFER_SIZE);
		krad_opus->samples[c] = malloc(16 * 8192);
		krad_opus->resampled_samples[c] = malloc(16 * 8192);
		krad_opus->src_resampler[c] = src_new (KRAD_OPUS_SRC_QUALITY, 1, &krad_opus->src_error[c]);
		if (krad_opus->src_resampler[c] == NULL) {
			failfast ("Krad Opus Encoder: src resampler error: %s", src_strerror (krad_opus->src_error[c]));
		}
		
		krad_opus->src_data[c].src_ratio = 48000.0 / krad_opus->input_sample_rate;
	}

	if (krad_opus->channels < 3) {

		krad_opus->streams = 1;
		
		if (krad_opus->channels == 2) {
			krad_opus->coupled_streams = 1;
			krad_opus->mapping[0] = 0;
			krad_opus->mapping[1] = 1;			
		} else {
			krad_opus->coupled_streams = 0;		
			krad_opus->mapping[0] = 0;
		}
		
		krad_opus->opus_header->channel_mapping = 0;

	} else {
		krad_opus->opus_header->channel_mapping = 1;

		switch (krad_opus->channels) {
			case 3:
				krad_opus->streams = 2;
				krad_opus->coupled_streams = 1;
				krad_opus->mapping[0] = 0;
				krad_opus->mapping[1] = 1;
				krad_opus->mapping[2] = 2;
			case 4:
				krad_opus->streams = 2;
				krad_opus->coupled_streams = 2;
				krad_opus->mapping[0] = 0;
				krad_opus->mapping[1] = 1;
				krad_opus->mapping[2] = 2;
				krad_opus->mapping[3] = 3;				
			case 5:
				krad_opus->streams = 3;
				krad_opus->coupled_streams = 2;
				krad_opus->mapping[0] = 0;
				krad_opus->mapping[1] = 4;
				krad_opus->mapping[2] = 1;
				krad_opus->mapping[3] = 2;				
				krad_opus->mapping[4] = 3;
			case 6:
				krad_opus->streams = 4;
				krad_opus->coupled_streams = 2;
				krad_opus->mapping[0] = 0;
				krad_opus->mapping[1] = 4;
				krad_opus->mapping[2] = 1;
				krad_opus->mapping[3] = 2;				
				krad_opus->mapping[4] = 3;
				krad_opus->mapping[5] = 5;
			case 7:
				krad_opus->streams = 5;
				krad_opus->coupled_streams = 2;
				krad_opus->mapping[0] = 0;
				krad_opus->mapping[1] = 4;
				krad_opus->mapping[2] = 1;
				krad_opus->mapping[3] = 2;				
				krad_opus->mapping[4] = 3;
				krad_opus->mapping[5] = 5;
				krad_opus->mapping[6] = 6;				
			case 8:
				krad_opus->streams = 5;
				krad_opus->coupled_streams = 3;
				krad_opus->mapping[0] = 0;
				krad_opus->mapping[1] = 6;
				krad_opus->mapping[2] = 1;
				krad_opus->mapping[3] = 2;				
				krad_opus->mapping[4] = 3;
				krad_opus->mapping[5] = 4;
				krad_opus->mapping[6] = 5;
				krad_opus->mapping[7] = 7;				
		}
	}
	
	krad_opus->opus_header->channels = krad_opus->channels;
	krad_opus->opus_header->nb_streams = krad_opus->streams;
	krad_opus->opus_header->nb_coupled = krad_opus->coupled_streams;
	
	memcpy (krad_opus->opus_header->stream_map, krad_opus->mapping, 256);

	krad_opus->encoder = opus_multistream_encoder_create (48000,
														  krad_opus->channels,
														  krad_opus->streams,
														  krad_opus->coupled_streams,
														  krad_opus->mapping,
														  krad_opus->application,
														  &krad_opus->err);

	if (krad_opus->err != OPUS_OK) {
		failfast ("Krad Opus Encoder: Cannot create encoder: %s", opus_strerror (krad_opus->err));
	}
	

	opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_GET_LOOKAHEAD (&krad_opus->lookahead));
	krad_opus->opus_header->preskip = krad_opus->lookahead;

	krad_opus->opus_header->gain = 0;
	krad_opus->opus_header->input_sample_rate = 48000;
	
	if (opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_BITRATE (krad_opus->bitrate)) != OPUS_OK) {
		failfast ("Krad Opus Encoder: bitrate request failed");
	}

	krad_opus->header_data_size = opus_header_to_packet (krad_opus->opus_header, krad_opus->header_data, 100);
	krad_opus->krad_codec_header.codec = OPUS;
	krad_opus->krad_codec_header.header[0] = krad_opus->header_data;
	krad_opus->krad_codec_header.header_size[0] = krad_opus->header_data_size;
	krad_opus->krad_codec_header.header_combined = krad_opus->header_data;
	krad_opus->krad_codec_header.header_combined_size = krad_opus->header_data_size;
	krad_opus->krad_codec_header.header_count = 2;

	krad_opus->krad_codec_header.header_size[1] = 
	8 + 4 + strlen (opus_get_version_string ()) + 4 + 4 + strlen ("ENCODER=") + strlen (APPVERSION);
	
	krad_opus->opustags_header = calloc (1, krad_opus->krad_codec_header.header_size[1]);
	
	memcpy (krad_opus->opustags_header, "OpusTags", 8);
	
	krad_opus->opustags_header[8] = strlen (opus_get_version_string ());
	
	memcpy (krad_opus->opustags_header + 12, opus_get_version_string (), strlen (opus_get_version_string ()));

	krad_opus->opustags_header[12 + strlen (opus_get_version_string ())] = 1;

	krad_opus->opustags_header[12 + strlen (opus_get_version_string ()) + 4] = strlen ("ENCODER=") + strlen (APPVERSION);
	
	memcpy (krad_opus->opustags_header + 12 + strlen (opus_get_version_string ()) + 4 + 4, "ENCODER=", strlen ("ENCODER="));
	
	memcpy (krad_opus->opustags_header + 12 + strlen (opus_get_version_string ()) + 4 + 4 + strlen ("ENCODER="),
			APPVERSION,
			strlen (APPVERSION));	
	
	krad_opus->krad_codec_header.header[1] = krad_opus->opustags_header;
	
	return krad_opus;

}