[opus] Why does this code not generate a valid opus file?

Daniel Armyr daniel at armyr.se
Sat Oct 17 13:26:54 PDT 2015


Hi.
I assume that I am deeply stupid and have missed something obvious, but why does this bare-bones code not generate a valid (If trivial) opus file? 

Running opusinfo I ge the following which I interpret this to mean that not even the first packet gets a pass:
New logical stream (#1, serial: 1f0cce42): type opus
WARNING: Could not decode Opus header packet 0 - invalid Opus stream (1)
WARNING: Could not decode Opus header packet 0 - invalid Opus stream (1)
Opus stream 1:
	WARNING: stream 1 is empty
Logical stream 1 ended

Here is my code:

#include <stdio.h>
#include <stdlib.h>
#include "ogg/ogg.h"

//Some structs to help build the headers.
struct OggHeader {
    unsigned char magicSignature[8];
    unsigned char version;
    unsigned char channelCount;
    unsigned short preSkip;
    unsigned int sampleRate;
    unsigned short outputGain;
    unsigned char mappingFamily;
};

struct OggCommentHeader {
    unsigned char magicSignature[8];
    unsigned int vendorStringLength; //Must be set to 0
    //In-between here we would place out vendor string, if we had one.
    unsigned int userCommentListLength; //Must be set to 0
    //And after here we would place our comments, if we had any.
};

int main(){
    ogg_stream_state os;
    ogg_page         og;
    
    FILE* fout = fopen("/tmp/trivial.opus", "wb");
    if ( fout == 0 ) {
        printf( "Error opening output file.\n" );
        return -1;
    }
    
    //**************
    //Initialize the stream
    srand(0);
    ogg_stream_init(&os,rand());
    
    //**************
    //Create the header
    //*****************
    struct OggHeader headerContent = {
        {'O', 'p', 'u', 's', 'H', 'e', 'a', 'd'},
        1, //Version
        2, //Channels
        0, //pre-skip
        44100, //Original samplerate
        0, //output gain
        0}; //Mapping family
    
    ogg_packet header;
    header.packet = (unsigned char*)&headerContent;
    header.bytes = sizeof(struct OggHeader);
    header.b_o_s = 1; //Header must set beginning_of_stream
    header.e_o_s = 0;
    header.granulepos = -1; //This packet does not contain audio data, so granule-position = -1
    header.packetno = 0;
    
    ogg_stream_packetin(&os,&header);
    
    //**************
    //Create the comments header
    struct OggCommentHeader commentHeaderContent = {
        {'O', 'p', 'u', 's', 'T', 'a', 'g', 's'},
        0, //We do not support a vandor string in this implementation.
        0 //We do not support any user comments in this implementation.
    };
    
    ogg_packet header_comm;
    header_comm.packet = (unsigned char*)&commentHeaderContent;
    header_comm.bytes = sizeof(struct OggCommentHeader);
    header_comm.b_o_s = 0;
    header_comm.e_o_s = 1; //We are ending the stream as there will be no data.
    header_comm.granulepos = -1; //This packet does not contain audio data, so granule-position = -1
    header_comm.packetno = 1; //Second packet.
    
    ogg_stream_packetin(&os,&header_comm);

    //***************
    //Write everything out.
    while(1){
        int result=ogg_stream_flush(&os,&og);
        if(result==0)break;
        fwrite(og.header,1,og.header_len,fout);
        fwrite(og.body,1,og.body_len,fout);
    }

    //And clean up.
    ogg_stream_clear(&os);
    
    fclose(fout);
    
    printf("Done.\n");
    return 0;
}

//Sincerely
Daniel Armyr
Beginner opus user
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.xiph.org/pipermail/opus/attachments/20151017/a0c223b1/attachment-0001.htm 


More information about the opus mailing list