Example #1
0
ComponentResult create_sample_description__flac(StreamInfo *si)
{
    ComponentResult err = noErr;
    Handle desc;
    AudioStreamBasicDescription asbd;
    AudioChannelLayout acl;
    AudioChannelLayout *pacl = &acl;
    ByteCount acl_size = sizeof(acl);

    asbd.mSampleRate = si->rate;
    asbd.mFormatID = kAudioFormatXiphOggFramedFLAC;
    asbd.mFormatFlags = 0;
    asbd.mBytesPerPacket = 0;
    asbd.mFramesPerPacket = 0;
    //asbd.mBytesPerFrame = 2 * si->numChannels;
    asbd.mBytesPerFrame = 0;
    asbd.mChannelsPerFrame = si->numChannels;
    //asbd.mBitsPerChannel = 16;
    //asbd.mBitsPerChannel = 0;
    asbd.mBitsPerChannel = si->si_flac.bps;
    asbd.mReserved = 0;

    acl.mChannelBitmap = 0;
    acl.mNumberChannelDescriptions = 0;
    switch (si->numChannels) {
    case 1:
        acl.mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
        break;
    case 2:
        acl.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
        break;
    case 3:
        acl.mChannelLayoutTag = kAudioChannelLayoutTag_ITU_3_0;
        break;
    case 4:
        acl.mChannelLayoutTag = kAudioChannelLayoutTag_Quadraphonic;
        break;
    case 5:
        acl.mChannelLayoutTag = kAudioChannelLayoutTag_ITU_3_2;
        break;
    case 6:
        acl.mChannelLayoutTag = kAudioChannelLayoutTag_ITU_3_2_1;
        break;
    default:
        pacl = NULL;
        acl_size = 0;
    }

    err = QTSoundDescriptionCreate(&asbd, pacl, acl_size, NULL, 0, kQTSoundDescriptionKind_Movie_Version2, (SoundDescriptionHandle*) &desc);

    if (err == noErr) {
        si->sampleDesc = (SampleDescriptionHandle) desc;
    }

    return err;
};
void ofxQtAudioRecorder::prepareAudioRecording(int sampleRate, int numChannels_){
	
	OSErr err = noErr;
	
	// create audio description and set format ID along with format flags, mBitsPerChannel and mBytesPerPacket
	AudioStreamBasicDescription asbd;
	
	numChannels = numChannels_;
	
	asbd.mSampleRate           = sampleRate;
    asbd.mFormatID             = kAudioFormatLinearPCM;
    asbd.mFormatFlags          = kAudioFormatFlagsNativeFloatPacked;
    // if multi-channel, the data format must be interleaved (non-interleaved is not allowed), 
    // and you should set up the asbd accordingly
    asbd.mChannelsPerFrame     = numChannels; // 2 (Stereo)
    // mBitsPerChannel = number of bits of sample data for each channel in a frame of data
    asbd.mBitsPerChannel       = sizeof (Float32) * 8; // was 8 // 32-bit floating point PCM
    // mBytesPerFrame = number of bytes in a single sample frame of data
    // (bytes per channel) * (channels per frame) = 4 * 2 = 8
    asbd.mBytesPerFrame        = (asbd.mBitsPerChannel>>3) * asbd.mChannelsPerFrame; // // number of *bytes* per channel * channels per frame
    asbd.mFramesPerPacket      = 1; // For PCM, frames per packet is always 1
    // mBytesPerPacket = (bytes per frame) * (frames per packet) = 8 * 1 = 8
    asbd.mBytesPerPacket       = asbd.mBytesPerFrame * asbd.mFramesPerPacket;
	
	//printf("bits per channel %i\n", asbd.mBitsPerChannel);
	//printf("bytes per frame %i - %i %i\n", asbd.mBytesPerFrame, (asbd.mBitsPerChannel>>3), asbd.mChannelsPerFrame);
	//printf("bytes per packet %i\n", asbd.mBytesPerPacket);
	
	err = QTSoundDescriptionCreate(&asbd,
								   NULL, 0,
								   NULL, 0,
								   kQTSoundDescriptionKind_Movie_Version2,
								   &soundDesc);
	checkErr(0x0200);
	
	audioTrack = NewMovieTrack(movie, Long2Fix(0), Long2Fix(0), kFullVolume);
	err = GetMoviesError();
	checkErr(0x0201);
	
	audioMedia = NewTrackMedia(audioTrack, SoundMediaType, sampleRate, NULL, 0);
	err = GetMoviesError();
	checkErr(0x0202);
	
	return;	
}
Example #3
0
ComponentResult create_sample_description__speex(StreamInfo *si)
{
    ComponentResult err = noErr;
    Handle desc;
    AudioStreamBasicDescription asbd;
    AudioChannelLayout acl;
    AudioChannelLayout *pacl = &acl;
    ByteCount acl_size = sizeof(acl);

    asbd.mSampleRate = si->rate;
    asbd.mFormatID = kAudioFormatXiphOggFramedSpeex;
    asbd.mFormatFlags = 0;
    asbd.mBytesPerPacket = 0;
    asbd.mFramesPerPacket = 0;
    //asbd.mBytesPerFrame = 2 * si->numChannels;
    asbd.mBytesPerFrame = 0;
    asbd.mChannelsPerFrame = si->numChannels;
    //asbd.mBitsPerChannel = 16;
    asbd.mBitsPerChannel = 0;
    asbd.mReserved = 0;

    if (si->numChannels == 1)
        acl.mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
    else if (si->numChannels == 2)
        acl.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
    else {
        pacl = NULL;
        acl_size = 0;
    }
    acl.mChannelBitmap = 0;
    acl.mNumberChannelDescriptions = 0;

    err = QTSoundDescriptionCreate(&asbd, pacl, acl_size, NULL, 0, kQTSoundDescriptionKind_Movie_Version2, (SoundDescriptionHandle*) &desc);

    if (err == noErr) {
        si->sampleDesc = (SampleDescriptionHandle) desc;
    }

    return err;
};
Example #4
0
static int init_audio(int speed, int channels, soundmovie_buffer_t **buffer)
{
    AudioStreamBasicDescription asbd = {0}; //see CoreAudioTypes.h

    asbd.mSampleRate = speed;
    asbd.mFormatID = kAudioFormatLinearPCM;
    asbd.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsSignedInteger;
    asbd.mChannelsPerFrame = channels;
    asbd.mBitsPerChannel = sizeof (SWORD) * 8;
    asbd.mBytesPerFrame = (asbd.mBitsPerChannel >> 3)      // number of *bytes* per channel
                          * asbd.mChannelsPerFrame;         // channels per frame
    asbd.mFramesPerPacket = 1;      // For PCM, frames per packet is always 1
    asbd.mBytesPerPacket = asbd.mBytesPerFrame * asbd.mFramesPerPacket;

    UInt32 layoutSize;
    layoutSize = offsetof(AudioChannelLayout, mChannelDescriptions[0]);
    AudioChannelLayout *layout = NULL;
    layout = calloc(layoutSize, 1);
    OSErr err = -1;
    if (layout != NULL) {
        if (channels == 1) {
            layout->mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
        } else if (channels == 2) {
            layout->mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
        } else {
            log_debug("quicktime_audio: unsupported channels: %d", channels);
            return -1;
        }
        err = QTSoundDescriptionCreate(
            &asbd,                      // format description
            layout, layoutSize,         // channel layout
            NULL, 0,                    // magic cookie (compression parameters)
            kQTSoundDescriptionKind_Movie_LowestPossibleVersion,
            &soundDescriptionHandle);         // SoundDescriptionHandle returned here
        free(layout);
    }
    if (err != noErr) {
        log_debug("quicktime_audio: error creating sound description!");
        return -1;
    }

    //Add audio track
    audioTrack = NewMovieTrack(movie, 0, 0, kFullVolume);
    OSStatus theError = GetMoviesError();
    if (theError) {
        log_debug("quicktime_audio: error creating movie track");
        return theError;
    }

    //Create audio track media
    audioMedia = NewTrackMedia(audioTrack, SoundMediaType, speed, 0, 0);
    theError = GetMoviesError();
    if (theError) {
        log_debug("quicktime_audio: error creating track media!");
        return theError;
    }

    //Prepare media for editing
    theError = BeginMediaEdits(audioMedia);
    if (theError) {
        log_debug("quicktime_audio: error beginning media edits!");
        return theError;
    }

    *buffer = &audioBuffer;
    audioBuffer.size = speed * channels / 10;
    audioBuffer.buffer = malloc(sizeof(SWORD) * audioBuffer.size);
    audioBuffer.used = 0;

    audio_ready = 1;
    return 0;
}
Example #5
0
/* Initializes the map & targetTrack to receive audio data */
OSStatus initialize_audio_map(NCStream *map, Track targetTrack, Handle dataRef, OSType dataRefType, AVPacket *firstFrame)
{
    Media media;
    SoundDescriptionHandle sndHdl = NULL;
    AudioStreamBasicDescription asbd;
    AVCodecContext *codec;
    UInt32 ioSize;
    OSStatus err = noErr;

    uint8_t *cookie = NULL;
    size_t cookieSize = 0;

    codec = map->str->codec;
    map->base = map->str->time_base;

    media = NewTrackMedia(targetTrack, SoundMediaType, codec->sample_rate, dataRef, dataRefType);

    map->media = media;

    memset(&asbd,0,sizeof(asbd));
    map_avi_to_mov_tag(codec->codec_id, &asbd, map, codec->channels);
    if(asbd.mFormatID == 0) /* no known codec, use the ms tag */
        asbd.mFormatID = 'ms\0\0' + codec->codec_tag; /* the number is stored in the last byte => big endian */

    /* Ask the AudioToolbox about vbr of the codec */
    ioSize = sizeof(UInt32);
    AudioFormatGetProperty(kAudioFormatProperty_FormatIsVBR, sizeof(AudioStreamBasicDescription), &asbd, &ioSize, &map->vbr);

    cookie = create_cookie(codec, &cookieSize, asbd.mFormatID, map->vbr);
    /* Set as much of the AudioStreamBasicDescription as possible.
     * Then ask the codec to correct it by calling FormatInfo before creating the SoundDescriptionHandle.
     * FormatInfo is poorly documented and doesn't set much of an example for 3rd party codecs but we can hope
     * they'll overwrite bad values here.
     */
    asbd.mSampleRate       = codec->sample_rate;
    asbd.mBytesPerPacket   = codec->block_align;
    asbd.mFramesPerPacket  = codec->frame_size;
    asbd.mChannelsPerFrame = codec->channels;
    asbd.mBitsPerChannel   = codec->bits_per_coded_sample;

    /* ask the toolbox about more information */
    ioSize = sizeof(AudioStreamBasicDescription);
    err = AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, cookieSize, cookie, &ioSize, &asbd);

    // We can't recover from this (FormatInfo resets mFormatID for bad MPEG-4 AOTs)
    if (!asbd.mFormatID || !asbd.mChannelsPerFrame) {
        Codecprintf(NULL, "Audio channels or format not set\n");
        goto bail;
    }

    // We might be able to recover from this (at least try to import the packets)
    if (err) {
        Codecprintf(NULL, "AudioFormatGetProperty failed (error %ld / format %lx)\n", err, asbd.mFormatID);
        err = noErr;
    }

    // This needs to be set for playback to work, but 10.4 (+ AppleTV) didn't set it in FormatInfo.
    // FIXME anything non-zero (like 1) might work here
    if (!asbd.mFramesPerPacket && asbd.mFormatID == kAudioFormatMPEGLayer3)
        asbd.mFramesPerPacket = asbd.mSampleRate > 24000 ? 1152 : 576;

    // if we don't have mBytesPerPacket, we can't import as CBR. Probably should be VBR, and the codec
    // either lied about kAudioFormatProperty_FormatIsVBR or isn't present
    if (asbd.mBytesPerPacket == 0)
        map->vbr = 1;

    /* If we have vbr audio, the media scale most likely has to be set to the time_base denumerator */
    if(map->vbr) {
        /* if we have mFramesPerPacket, set mBytesPerPacket to 0 as this can cause
         * errors if set incorrectly. But in vbr, we just need the mFramesPerPacket
         * value */
        if(asbd.mFramesPerPacket)
            asbd.mBytesPerPacket = 0;

        SetMediaTimeScale(media, map->str->time_base.den);
    }

    if (asbd.mFormatID == kAudioFormatLinearPCM)
        asbd.mFramesPerPacket = 1;
    else if (asbd.mBytesPerPacket) {
        /* FIXME: in the MSADPCM codec, we get a wrong mFramesPerPacket entry because
         * of the difference in the sample_rate and the time_base denumerator. So we
         * recalculate here the mFramesPerPacket entry */

        /* For calculation, lets assume a packet duration of 1, use ioSize as tmp storage */
        ioSize = map->str->time_base.num * codec->sample_rate / map->str->time_base.den;
        /* downscale to correct bytes_per_packet */
        asbd.mFramesPerPacket = ioSize * asbd.mBytesPerPacket / codec->block_align;
    }

    AudioChannelLayout acl;
    int aclSize = 0;  //Set this if you intend to use it
    memset(&acl, 0, sizeof(AudioChannelLayout));

    /* We have to parse the format */
    int useDefault = 1;
    if(asbd.mFormatID == kAudioFormatAC3 || asbd.mFormatID == 'ms \0')
    {
        QTMetaDataRef trackMetaData;
        OSStatus error = QTCopyTrackMetaData(targetTrack, &trackMetaData);
        if(error == noErr)
        {
            const char *prop = "Surround";
            OSType key = 'name';
            QTMetaDataAddItem(trackMetaData, kQTMetaDataStorageFormatUserData, kQTMetaDataKeyFormatUserData, (UInt8 *)&key, sizeof(key), (UInt8 *)prop, strlen(prop), kQTMetaDataTypeUTF8, NULL);
            QTMetaDataRelease(trackMetaData);
        }
        if(parse_ac3_bitstream(&asbd, &acl, firstFrame->data, firstFrame->size))
        {
            useDefault = 0;
            aclSize = sizeof(AudioChannelLayout);
        }
    }
    if(useDefault && asbd.mChannelsPerFrame > 2)
    {
        acl = GetDefaultChannelLayout(&asbd);
        aclSize = sizeof(AudioChannelLayout);
    }

    if (asbd.mSampleRate > 0) {
        err = QTSoundDescriptionCreate(&asbd, aclSize == 0 ? NULL : &acl, aclSize, cookie, cookieSize, kQTSoundDescriptionKind_Movie_LowestPossibleVersion, &sndHdl);

        if(err) {
            fprintf(stderr, "AVI IMPORTER: Error %ld creating the sound description\n", err);
            goto bail;
        }
    }
    map->sampleHdl = (SampleDescriptionHandle)sndHdl;
    map->asbd = asbd;

bail:
    if(cookie)
        av_free(cookie);

    return err;
} /* initialize_audio_map() */