Ejemplo n.º 1
0
int CMP4Tag::WriteMP4Tag(MP4FileHandle MP4File)
{
char	buf[512], *faac_id_string, *faac_copyright_string;

	if(MP4File==NULL)
	{
		MessageBox(NULL,"WriteMp4Tag: can't open file!",NULL,MB_OK);
		return 1;
	}

	sprintf(buf, "FAAC v%s", (faacEncGetVersion(&faac_id_string, &faac_copyright_string)==FAAC_CFG_VERSION) ? faac_id_string : " wrong libfaac version");
	MP4SetMetadataTool(MP4File, buf);

	if(artist) MP4SetMetadataArtist(MP4File, artist);
	if(writer) MP4SetMetadataWriter(MP4File, writer);
	if(title) MP4SetMetadataName(MP4File, title);
	if(album) MP4SetMetadataAlbum(MP4File, album);
	if(trackno>0) MP4SetMetadataTrack(MP4File, trackno, ntracks);
	if(discno>0) MP4SetMetadataDisk(MP4File, discno, ndiscs);
	if(compilation) MP4SetMetadataCompilation(MP4File, compilation);
	if(year) MP4SetMetadataYear(MP4File, year);
	if(genre) MP4SetMetadataGenre(MP4File, genre);
	if(comment) MP4SetMetadataComment(MP4File, comment);
	if(art.size=ReadCoverArtFile(artFilename,&art.data))
	{
		MP4SetMetadataCoverArt(MP4File, (unsigned __int8 *)art.data, art.size);
		FREE_ARRAY(art.data);
	}
	return 0;
}
Ejemplo n.º 2
0
int
main(int argc, char** argv)
{
    static struct option long_options[] = {
        { "help",    0, 0, OPT_HELP    },
        { "version", 0, 0, OPT_VERSION },
        { "album",   1, 0, OPT_ALBUM   },
        { "artist",  1, 0, OPT_ARTIST  },
        { "comment", 1, 0, OPT_COMMENT },
        { "disk",    1, 0, OPT_DISK    },
        { "disks",   1, 0, OPT_DISKS   },
        { "genre",   1, 0, OPT_GENRE   },
        { "song",    1, 0, OPT_SONG    },
        { "tempo",   1, 0, OPT_TEMPO   },
        { "track",   1, 0, OPT_TRACK   },
        { "tracks",  1, 0, OPT_TRACKS  },
        { "writer",  1, 0, OPT_WRITER  },
        { "year",    1, 0, OPT_YEAR    },
        { NULL,      0, 0, 0 }
    };

    /* Sparse arrays of tag data: some space is wasted, but it's more
       convenient to say tags[OPT_SONG] than to enumerate all the
       metadata types (again) as a struct. */
    char *tags[UCHAR_MAX] = { 0 };
    int nums[UCHAR_MAX] = { 0 };

    /* Any modifications requested? */
    int mods = 0;

    /* Option-processing loop. */
    int c = getopt_long_only(argc, argv, OPT_STRING, long_options, NULL);
    while (c != -1) {
        int r = 2;
        switch(c) {
        /* getopt() returns '?' if there was an error.  It already
           printed the error message, so just return. */
        case '?':
            return 1;

        /* Help and version requests handled here. */
        case OPT_HELP:
            fprintf(stderr, "usage %s %s", argv[0], help_text);
            return 0;
        case OPT_VERSION:
            fprintf(stderr, "%s - %s version %s\n", argv[0], MPEG4IP_PACKAGE,
                    MPEG4IP_VERSION);
            return 0;

        /* Numeric arguments: convert them using sscanf(). */
        case OPT_DISK:
        case OPT_DISKS:
        case OPT_TRACK:
        case OPT_TRACKS:
        case OPT_TEMPO:
            r = sscanf(optarg, "%d", &nums[c]);
            if (r < 1) {
                fprintf(stderr, "%s: option requires numeric argument -- %c\n",
                        argv[0], c);
                return 2;
            }
        /* Break not, lest ye be broken.  :) */
        /* All arguments: all valid options end up here, and we just
           stuff the string pointer into the tags[] array. */
        default:
            tags[c] = optarg;
            mods++;
        } /* end switch */

        c = getopt_long_only(argc, argv, OPT_STRING, long_options, NULL);
    } /* end while */

    /* Check that we have at least one non-option argument */
    if ((argc - optind) < 1) {
        fprintf(stderr,
                "%s: You must specify at least one MP4 file.\n",
                argv[0]);
        fprintf(stderr, "usage %s %s", argv[0], help_text);
        return 3;
    }

    /* Check that we have at least one requested modification.  Probably
       it's useful instead to print the metadata if no modifications are
       requested? */
    if (!mods) {
        fprintf(stderr,
                "%s: You must specify at least one tag modification.\n",
                argv[0]);
        fprintf(stderr, "usage %s %s", argv[0], help_text);
        return 4;
    }

    /* Loop through the non-option arguments, and modify the tags as
       requested. */
    while (optind < argc) {
        char *mp4 = argv[optind++];

        MP4FileHandle h = MP4Modify(mp4);
        if (h == MP4_INVALID_FILE_HANDLE) {
            fprintf(stderr, "Could not open '%s'... aborting\n", mp4);
            return 5;
        }

        /* Track/disk numbers need to be set all at once, but we'd like to
           allow users to just specify -T 12 to indicate that all existing
           track numbers are out of 12.  This means we need to look up the
           current info if it is not being set. */
        uint16_t n0, m0, n1, m1;

        if (tags[OPT_TRACK] || tags[OPT_TRACKS]) {
            MP4GetMetadataTrack(h, &n0, &m0);
            n1 = tags[OPT_TRACK]? nums[OPT_TRACK] : n0;
            m1 = tags[OPT_TRACKS]? nums[OPT_TRACKS] : m0;
            MP4SetMetadataTrack(h, n1, m1);
        }
        if (tags[OPT_DISK] || tags[OPT_DISKS]) {
            MP4GetMetadataDisk(h, &n0, &m0);
            n1 = tags[OPT_DISK]? nums[OPT_DISK] : n0;
            m1 = tags[OPT_DISKS]? nums[OPT_DISKS] : m0;
            MP4SetMetadataDisk(h, n1, m1);
        }

        /* Set the other relevant attributes */
        for (int i = 0;  i < UCHAR_MAX;  i++) {
            if (tags[i]) {
                switch(i) {
                case OPT_ALBUM:
                    MP4SetMetadataAlbum(h, tags[i]);
                    break;
                case OPT_ARTIST:
                    MP4SetMetadataArtist(h, tags[i]);
                    break;
                case OPT_COMMENT:
                    MP4SetMetadataComment(h, tags[i]);
                    break;
                case OPT_GENRE:
                    MP4SetMetadataGenre(h, tags[i]);
                    break;
                case OPT_SONG:
                    MP4SetMetadataName(h, tags[i]);
                    break;
                case OPT_WRITER:
                    MP4SetMetadataWriter(h, tags[i]);
                    break;
                case OPT_YEAR:
                    MP4SetMetadataYear(h, tags[i]);
                    break;
                case OPT_TEMPO:
                    MP4SetMetadataTempo(h, nums[i]);
                    break;
                }
            }
        }
        MP4Close(h);
    } /* end while optind < argc */

    return 0;
}
Ejemplo n.º 3
0
int main(int argc, char *argv[])
{
    int frames, currentFrame;
    faacEncHandle hEncoder;
    pcmfile_t *infile = NULL;

    unsigned long samplesInput, maxBytesOutput, totalBytesWritten=0;

    faacEncConfigurationPtr myFormat;
    unsigned int mpegVersion = MPEG2;
    unsigned int objectType = LOW;
    unsigned int useMidSide = 1;
    static unsigned int useTns = DEFAULT_TNS;
    enum container_format container = NO_CONTAINER;
    int optimizeFlag = 0;
    enum stream_format stream = ADTS_STREAM;
    int cutOff = -1;
    int bitRate = 0;
    unsigned long quantqual = 0;
    int chanC = 3;
    int chanLF = 4;

    char *audioFileName = NULL;
    char *aacFileName = NULL;
    char *aacFileExt = NULL;
    int aacFileNameGiven = 0;

    float *pcmbuf;
    int *chanmap = NULL;

    unsigned char *bitbuf;
    int samplesRead = 0;
    const char *dieMessage = NULL;

    int rawChans = 0; // disabled by default
    int rawBits = 16;
    int rawRate = 44100;
    int rawEndian = 1;

    int shortctl = SHORTCTL_NORMAL;

    FILE *outfile = NULL;

#ifdef HAVE_LIBMP4V2
    MP4FileHandle MP4hFile = MP4_INVALID_FILE_HANDLE;
    MP4TrackId MP4track = 0;
    unsigned int ntracks = 0, trackno = 0;
    unsigned int ndiscs = 0, discno = 0;
    u_int8_t compilation = 0;
    const char *artist = NULL, *title = NULL, *album = NULL, *year = NULL,
      *genre = NULL, *comment = NULL, *writer = NULL;
    u_int8_t *art = NULL;
    u_int64_t artSize = 0;
    u_int64_t total_samples = 0;
    u_int64_t encoded_samples = 0;
    unsigned int delay_samples;
    unsigned int frameSize;
#endif
    char *faac_id_string;
    char *faac_copyright_string;

#ifndef _WIN32
    // install signal handler
    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);
#endif

    // get faac version
    if (faacEncGetVersion(&faac_id_string, &faac_copyright_string) == FAAC_CFG_VERSION)
    {
        fprintf(stderr, "Freeware Advanced Audio Coder\nFAAC %s\n\n", faac_id_string);
    }
    else
    {
        fprintf(stderr, __FILE__ "(%d): wrong libfaac version\n", __LINE__);
        return 1;
    }

    /* begin process command line */
    progName = argv[0];
    while (1) {
        static struct option long_options[] = {
            { "help", 0, 0, 'h'},
            { "long-help", 0, 0, 'H'},
            { "raw", 0, 0, 'r'},
            { "no-midside", 0, 0, NO_MIDSIDE_FLAG},
            { "cutoff", 1, 0, 'c'},
            { "quality", 1, 0, 'q'},
            { "pcmraw", 0, 0, 'P'},
            { "pcmsamplerate", 1, 0, 'R'},
            { "pcmsamplebits", 1, 0, 'B'},
            { "pcmchannels", 1, 0, 'C'},
            { "shortctl", 1, 0, SHORTCTL_FLAG},
            { "tns", 0, 0, TNS_FLAG},
            { "no-tns", 0, 0, NO_TNS_FLAG},
            { "mpeg-version", 1, 0, MPEGVERS_FLAG},
            { "obj-type", 1, 0, OBJTYPE_FLAG},
            { "license", 0, 0, 'L'},
#ifdef HAVE_LIBMP4V2
            { "createmp4", 0, 0, 'w'},
            { "optimize", 0, 0, 's'},
            { "artist", 1, 0, ARTIST_FLAG},
            { "title", 1, 0, TITLE_FLAG},
            { "album", 1, 0, ALBUM_FLAG},
            { "track", 1, 0, TRACK_FLAG},
            { "disc", 1, 0, DISC_FLAG},
            { "genre", 1, 0, GENRE_FLAG},
            { "year", 1, 0, YEAR_FLAG},
            { "cover-art", 1, 0, COVER_ART_FLAG},
            { "comment", 1, 0, COMMENT_FLAG},
        { "writer", 1, 0, WRITER_FLAG},
        { "compilation", 0, 0, COMPILATION_FLAG},
#endif
        { "pcmswapbytes", 0, 0, 'X'},
            { 0, 0, 0, 0}
        };
        int c = -1;
        int option_index = 0;

        c = getopt_long(argc, argv, "Hhb:m:o:rnc:q:PR:B:C:I:X"
#ifdef HAVE_LIBMP4V2
                        "ws"
#endif
            ,long_options, &option_index);

        if (c == -1)
            break;

        if (!c)
        {
          dieMessage = usage;
          break;
        }

        switch (c) {
    case 'o':
        {
            int l = strlen(optarg);
        aacFileName = malloc(l+1);
        memcpy(aacFileName, optarg, l);
        aacFileName[l] = '\0';
        aacFileNameGiven = 1;
        }
        break;
        case 'r': {
            stream = RAW_STREAM;
            break;
        }
        case NO_MIDSIDE_FLAG: {
            useMidSide = 0;
            break;
        }
        case 'c': {
            unsigned int i;
            if (sscanf(optarg, "%u", &i) > 0) {
                cutOff = i;
            }
            break;
        }
        case 'b': {
            unsigned int i;
            if (sscanf(optarg, "%u", &i) > 0)
            {
                bitRate = 1000 * i;
            }
            break;
        }
        case 'q':
        {
            unsigned int i;
            if (sscanf(optarg, "%u", &i) > 0)
            {
                if (i > 0 && i < 1000)
                    quantqual = i;
            }
            break;
        }
        case 'I':
            sscanf(optarg, "%d,%d", &chanC, &chanLF);
            break;
        case 'P':
            rawChans = 2; // enable raw input
            break;
        case 'R':
        {
            unsigned int i;
            if (sscanf(optarg, "%u", &i) > 0)
            {
                rawRate = i;
                rawChans = (rawChans > 0) ? rawChans : 2;
            }
            break;
        }
        case 'B':
        {
            unsigned int i;
            if (sscanf(optarg, "%u", &i) > 0)
            {
                if (i > 32)
                    i = 32;
                if (i < 8)
                    i = 8;
                rawBits = i;
                rawChans = (rawChans > 0) ? rawChans : 2;
            }
            break;
        }
        case 'C':
        {
            unsigned int i;
            if (sscanf(optarg, "%u", &i) > 0)
                rawChans = i;
            break;
        }
#ifdef HAVE_LIBMP4V2
        case 'w':
        container = MP4_CONTAINER;
            break;
        case 's':
        optimizeFlag = 1;
            break;
    case ARTIST_FLAG:
        artist = optarg;
        break;
    case WRITER_FLAG:
        writer = optarg;
        break;
    case TITLE_FLAG:
        title = optarg;
        break;
    case ALBUM_FLAG:
        album = optarg;
        break;
    case TRACK_FLAG:
        sscanf(optarg, "%d/%d", &trackno, &ntracks);
        break;
    case DISC_FLAG:
        sscanf(optarg, "%d/%d", &discno, &ndiscs);
        break;
    case COMPILATION_FLAG:
        compilation = 0x1;
        break;
    case GENRE_FLAG:
        genre = optarg;
        break;
    case YEAR_FLAG:
        year = optarg;
        break;
    case COMMENT_FLAG:
        comment = optarg;
        break;
    case COVER_ART_FLAG: {
        FILE *artFile = fopen(optarg, "rb");

        if(artFile) {
            u_int64_t r;

            fseek(artFile, 0, SEEK_END);
        artSize = ftell(artFile);

        art = malloc(artSize);

            fseek(artFile, 0, SEEK_SET);
        clearerr(artFile);

        r = fread(art, artSize, 1, artFile);

        if (r != 1) {
            dieMessage = "Error reading cover art file!\n";
            free(art);
            art = NULL;
        } else if (artSize < 12 || !check_image_header(art)) {
            /* the above expression checks the image signature */
            dieMessage = "Unsupported cover image file format!\n";
            free(art);
            art = NULL;
        }

        fclose(artFile);
        } else {
            dieMessage = "Error opening cover art file!\n";
        }

        break;
    }
#endif
        case SHORTCTL_FLAG:
            shortctl = atoi(optarg);
            break;
        case TNS_FLAG:
            useTns = 1;
            break;
        case NO_TNS_FLAG:
            useTns = 0;
            break;
    case MPEGVERS_FLAG:
            mpegVersion = atoi(optarg);
            switch(mpegVersion)
            {
            case 2:
                mpegVersion = MPEG2;
                break;
            case 4:
                mpegVersion = MPEG4;
                break;
            default:
            dieMessage = "Unrecognised MPEG version!\n";
            }
            break;
#if 0
    case OBJTYPE_FLAG:
        if (!strcasecmp(optarg, "LC"))
                objectType = LOW;
        else if (!strcasecmp(optarg, "Main"))
            objectType = MAIN;
        else if (!strcasecmp(optarg, "LTP")) {
            mpegVersion = MPEG4;
        objectType = LTP;
        } else
            dieMessage = "Unrecognised object type!\n";
        break;
#endif
        case 'L':
        fprintf(stderr, faac_copyright_string);
        dieMessage = license;
        break;
    case 'X':
      rawEndian = 0;
      break;
    case 'H':
      dieMessage = long_help;
      break;
    case 'h':
          dieMessage = short_help;
      break;
    case '?':
        default:
      dieMessage = usage;
          break;
        }
    }

    /* check that we have at least one non-option arguments */
    if (!dieMessage && (argc - optind) > 1 && aacFileNameGiven)
        dieMessage = "Cannot encode several input files to one output file.\n";

    if (argc - optind < 1 || dieMessage)
    {
        fprintf(stderr, dieMessage ? dieMessage : usage,
           progName, progName, progName, progName);
        return 1;
    }

    while (argc - optind > 0) {

    /* get the input file name */
    audioFileName = argv[optind++];

    /* generate the output file name, if necessary */
    if (!aacFileNameGiven) {
        char *t = strrchr(audioFileName, '.');
    int l = t ? strlen(audioFileName) - strlen(t) : strlen(audioFileName);

#ifdef HAVE_LIBMP4V2
    aacFileExt = container == MP4_CONTAINER ? ".m4a" : ".aac";
#else
    aacFileExt = ".aac";
#endif

    aacFileName = malloc(l+1+4);
    memcpy(aacFileName, audioFileName, l);
    memcpy(aacFileName + l, aacFileExt, 4);
    aacFileName[l+4] = '\0';
    } else {
        aacFileExt = strrchr(aacFileName, '.');

        if (aacFileExt && (!strcmp(".m4a", aacFileExt) || !strcmp(".m4b", aacFileExt) || !strcmp(".mp4", aacFileExt)))
#ifndef HAVE_LIBMP4V2
        fprintf(stderr, "WARNING: MP4 support unavailable!\n");
#else
        container = MP4_CONTAINER;
#endif
    }

    /* open the audio input file */
    if (rawChans > 0) // use raw input
    {
        infile = wav_open_read(audioFileName, 1);
    if (infile)
    {
        infile->bigendian = rawEndian;
        infile->channels = rawChans;
        infile->samplebytes = rawBits / 8;
        infile->samplerate = rawRate;
        infile->samples /= (infile->channels * infile->samplebytes);
    }
    }
    else // header input
        infile = wav_open_read(audioFileName, 0);

    if (infile == NULL)
    {
        fprintf(stderr, "Couldn't open input file %s\n", audioFileName);
    return 1;
    }


    /* open the encoder library */
    hEncoder = faacEncOpen(infile->samplerate, infile->channels,
        &samplesInput, &maxBytesOutput);

#ifdef HAVE_LIBMP4V2
    if (container != MP4_CONTAINER && (ntracks || trackno || artist ||
                       title ||  album || year || art ||
                       genre || comment || discno || ndiscs ||
                       writer || compilation))
    {
        fprintf(stderr, "Metadata requires MP4 output!\n");
    return 1;
    }

    if (container == MP4_CONTAINER)
    {
        mpegVersion = MPEG4;
    stream = RAW_STREAM;
    }

    frameSize = samplesInput/infile->channels;
    delay_samples = frameSize; // encoder delay 1024 samples
#endif
    pcmbuf = (float *)malloc(samplesInput*sizeof(float));
    bitbuf = (unsigned char*)malloc(maxBytesOutput*sizeof(unsigned char));
    chanmap = mkChanMap(infile->channels, chanC, chanLF);
    if (chanmap)
    {
        fprintf(stderr, "Remapping input channels: Center=%d, LFE=%d\n",
            chanC, chanLF);
    }

    if (cutOff <= 0)
    {
        if (cutOff < 0) // default
            cutOff = 0;
        else // disabled
            cutOff = infile->samplerate / 2;
    }
    if (cutOff > (infile->samplerate / 2))
        cutOff = infile->samplerate / 2;

    /* put the options in the configuration struct */
    myFormat = faacEncGetCurrentConfiguration(hEncoder);
    myFormat->aacObjectType = objectType;
    myFormat->mpegVersion = mpegVersion;
    myFormat->useTns = useTns;
    switch (shortctl)
    {
    case SHORTCTL_NOSHORT:
      fprintf(stderr, "disabling short blocks\n");
      myFormat->shortctl = shortctl;
      break;
    case SHORTCTL_NOLONG:
      fprintf(stderr, "disabling long blocks\n");
      myFormat->shortctl = shortctl;
      break;
    }
    if (infile->channels >= 6)
        myFormat->useLfe = 1;
    myFormat->allowMidside = useMidSide;
    if (bitRate)
        myFormat->bitRate = bitRate / infile->channels;
    myFormat->bandWidth = cutOff;
    if (quantqual > 0)
        myFormat->quantqual = quantqual;
    myFormat->outputFormat = stream;
    myFormat->inputFormat = FAAC_INPUT_FLOAT;
    if (!faacEncSetConfiguration(hEncoder, myFormat)) {
        fprintf(stderr, "Unsupported output format!\n");
#ifdef HAVE_LIBMP4V2
        if (container == MP4_CONTAINER) MP4Close(MP4hFile);
#endif
        return 1;
    }

#ifdef HAVE_LIBMP4V2
    /* initialize MP4 creation */
    if (container == MP4_CONTAINER) {
        unsigned char *ASC = 0;
        unsigned long ASCLength = 0;
    char *version_string;

#ifdef MP4_CREATE_EXTENSIBLE_FORMAT
    /* hack to compile against libmp4v2 >= 1.0RC3
     * why is there no version identifier in mp4.h? */
        MP4hFile = MP4Create(aacFileName, MP4_DETAILS_ERROR, 0);
#else
    MP4hFile = MP4Create(aacFileName, MP4_DETAILS_ERROR, 0, 0);
#endif
        if (!MP4_IS_VALID_FILE_HANDLE(MP4hFile)) {
            fprintf(stderr, "Couldn't create output file %s\n", aacFileName);
            return 1;
        }

        MP4SetTimeScale(MP4hFile, 90000);
        MP4track = MP4AddAudioTrack(MP4hFile, infile->samplerate, MP4_INVALID_DURATION, MP4_MPEG4_AUDIO_TYPE);
        MP4SetAudioProfileLevel(MP4hFile, 0x0F);
        faacEncGetDecoderSpecificInfo(hEncoder, &ASC, &ASCLength);
        MP4SetTrackESConfiguration(MP4hFile, MP4track, ASC, ASCLength);
    free(ASC);

    /* set metadata */
    version_string = malloc(strlen(faac_id_string) + 6);
    strcpy(version_string, "FAAC ");
    strcpy(version_string + 5, faac_id_string);
    MP4SetMetadataTool(MP4hFile, version_string);
    free(version_string);

    if (artist) MP4SetMetadataArtist(MP4hFile, artist);
    if (writer) MP4SetMetadataWriter(MP4hFile, writer);
    if (title) MP4SetMetadataName(MP4hFile, title);
    if (album) MP4SetMetadataAlbum(MP4hFile, album);
    if (trackno > 0) MP4SetMetadataTrack(MP4hFile, trackno, ntracks);
    if (discno > 0) MP4SetMetadataDisk(MP4hFile, discno, ndiscs);
    if (compilation) MP4SetMetadataCompilation(MP4hFile, compilation);
    if (year) MP4SetMetadataYear(MP4hFile, year);
    if (genre) MP4SetMetadataGenre(MP4hFile, genre);
    if (comment) MP4SetMetadataComment(MP4hFile, comment);
        if (artSize) {
        MP4SetMetadataCoverArt(MP4hFile, art, artSize);
        free(art);
    }
    }
    else
    {
#endif
        /* open the aac output file */
        if (!strcmp(aacFileName, "-"))
        {
            outfile = stdout;
        }
        else
        {
            outfile = fopen(aacFileName, "wb");
        }
        if (!outfile)
        {
            fprintf(stderr, "Couldn't create output file %s\n", aacFileName);
            return 1;
        }
#ifdef HAVE_LIBMP4V2
    }
#endif

    cutOff = myFormat->bandWidth;
    quantqual = myFormat->quantqual;
    bitRate = myFormat->bitRate;
    if (bitRate)
      fprintf(stderr, "Average bitrate: %d kbps\n",
          (bitRate + 500)/1000*infile->channels);
    fprintf(stderr, "Quantization quality: %ld\n", quantqual);
    fprintf(stderr, "Bandwidth: %d Hz\n", cutOff);
    fprintf(stderr, "Object type: ");
    switch(objectType)
    {
    case LOW:
        fprintf(stderr, "Low Complexity");
        break;
    case MAIN:
        fprintf(stderr, "Main");
        break;
    case LTP:
        fprintf(stderr, "LTP");
        break;
    }
    fprintf(stderr, "(MPEG-%d)", (mpegVersion == MPEG4) ? 4 : 2);
    if (myFormat->useTns)
        fprintf(stderr, " + TNS");
    if (myFormat->allowMidside)
        fprintf(stderr, " + M/S");
    fprintf(stderr, "\n");

    fprintf(stderr, "Container format: ");
    switch(container)
    {
    case NO_CONTAINER:
      switch(stream)
    {
    case RAW_STREAM:
      fprintf(stderr, "Headerless AAC (RAW)\n");
      break;
    case ADTS_STREAM:
      fprintf(stderr, "Transport Stream (ADTS)\n");
      break;
    }
        break;
#ifdef HAVE_LIBMP4V2
    case MP4_CONTAINER:
        fprintf(stderr, "MPEG-4 File Format (MP4)\n");
        break;
#endif
    }

    if (outfile
#ifdef HAVE_LIBMP4V2
        || MP4hFile != MP4_INVALID_FILE_HANDLE
#endif
       )
    {
        int showcnt = 0;
#ifdef _WIN32
        long begin = GetTickCount();
#endif
        if (infile->samples)
            frames = ((infile->samples + 1023) / 1024) + 1;
        else
            frames = 0;
        currentFrame = 0;

        fprintf(stderr, "Encoding %s to %s\n", audioFileName, aacFileName);
        if (frames != 0)
            fprintf(stderr, "   frame          | bitrate | elapsed/estim | "
            "play/CPU | ETA\n");
        else
            fprintf(stderr, " frame | elapsed | play/CPU\n");

        /* encoding loop */
#ifdef _WIN32
    for (;;)
#else
        while (running)
#endif
        {
            int bytesWritten;

            samplesRead = wav_read_float32(infile, pcmbuf, samplesInput, chanmap);

#ifdef HAVE_LIBMP4V2
            total_samples += samplesRead / infile->channels;
#endif

            /* call the actual encoding routine */
            bytesWritten = faacEncEncode(hEncoder,
                (int32_t *)pcmbuf,
                samplesRead,
                bitbuf,
                maxBytesOutput);

            if (bytesWritten)
            {
                currentFrame++;
                showcnt--;
        totalBytesWritten += bytesWritten;
            }

            if ((showcnt <= 0) || !bytesWritten)
            {
                double timeused;
#ifdef __unix__
                struct rusage usage;
#endif
#ifdef _WIN32
                char percent[MAX_PATH + 20];
                timeused = (GetTickCount() - begin) * 1e-3;
#else
#ifdef __unix__
                if (getrusage(RUSAGE_SELF, &usage) == 0) {
                    timeused = (double)usage.ru_utime.tv_sec +
                        (double)usage.ru_utime.tv_usec * 1e-6;
                }
                else
                    timeused = 0;
#else
                timeused = (double)clock() * (1.0 / CLOCKS_PER_SEC);
#endif
#endif
                if (currentFrame && (timeused > 0.1))
                {
                    showcnt += 50;

                    if (frames != 0)
                        fprintf(stderr,
                            "\r%5d/%-5d (%3d%%)|  %5.1f  | %6.1f/%-6.1f | %7.2fx | %.1f ",
                            currentFrame, frames, currentFrame*100/frames,
                ((double)totalBytesWritten * 8.0 / 1000.0) /
                ((double)infile->samples / infile->samplerate * currentFrame / frames),
                            timeused,
                            timeused * frames / currentFrame,
                            (1024.0 * currentFrame / infile->samplerate) / timeused,
                            timeused  * (frames - currentFrame) / currentFrame);
                    else
                        fprintf(stderr,
                            "\r %5d |  %6.1f | %7.2fx ",
                            currentFrame,
                            timeused,
                            (1024.0 * currentFrame / infile->samplerate) / timeused);

                    fflush(stderr);
#ifdef _WIN32
                    if (frames != 0)
                    {
                        sprintf(percent, "%.2f%% encoding %s",
                            100.0 * currentFrame / frames, audioFileName);
                        SetConsoleTitle(percent);
                    }
#endif
                }
            }

            /* all done, bail out */
            if (!samplesRead && !bytesWritten)
                break ;

            if (bytesWritten < 0)
            {
                fprintf(stderr, "faacEncEncode() failed\n");
                break ;
            }

            if (bytesWritten > 0)
            {
#ifdef HAVE_LIBMP4V2
                u_int64_t samples_left = total_samples - encoded_samples + delay_samples;
                MP4Duration dur = samples_left > frameSize ? frameSize : samples_left;
                MP4Duration ofs = encoded_samples > 0 ? 0 : delay_samples;

                if (container == MP4_CONTAINER)
                {
                    /* write bitstream to mp4 file */
                    MP4WriteSample(MP4hFile, MP4track, bitbuf, bytesWritten, dur, ofs, 1);
                }
                else
                {
#endif
                    /* write bitstream to aac file */
                    fwrite(bitbuf, 1, bytesWritten, outfile);
#ifdef HAVE_LIBMP4V2
                }

                encoded_samples += dur;
#endif
            }
        }

#ifdef HAVE_LIBMP4V2
        /* clean up */
        if (container == MP4_CONTAINER)
        {
            MP4Close(MP4hFile);
            if (optimizeFlag == 1)
            {
                fprintf(stderr, "\n\nMP4 format optimization... ");
                MP4Optimize(aacFileName, NULL, 0);
                fprintf(stderr, "Done!");
            }
        } else
#endif
            fclose(outfile);

        fprintf(stderr, "\n\n");
    }

    faacEncClose(hEncoder);

    wav_close(infile);

    if (pcmbuf) free(pcmbuf);
    if (bitbuf) free(bitbuf);
    if (aacFileNameGiven) free(aacFileName);

    }

    return 0;
}
Ejemplo n.º 4
0
int mp4_set_metadata(MP4FileHandle file, const char *item, const char *val)
{
    if (!item || (item && !*item) || !val || (val && !*val)) return 0;

    if (!stricmp(item, "track") || !stricmp(item, "tracknumber"))
    {
        unsigned __int16 trkn, tot;
        int t1 = 0, t2 = 0;
        sscanf(val, "%d/%d", &t1, &t2);
        trkn = t1, tot = t2;
        if (!trkn) return 1;
        if (MP4SetMetadataTrack(file, trkn, tot)) return 1;
    }
    else if (!stricmp(item, "disc") || !stricmp(item, "disknumber"))
    {
        unsigned __int16 disk, tot;
        int t1 = 0, t2 = 0;
        sscanf(val, "%d/%d", &t1, &t2);
        disk = t1, tot = t2;
        if (!disk) return 1;
        if (MP4SetMetadataDisk(file, disk, tot)) return 1;
    }
    else if (!stricmp(item, "compilation"))
    {
        unsigned __int8 cpil = atoi(val);
        if (!cpil) return 1;
        if (MP4SetMetadataCompilation(file, cpil)) return 1;
    }
    else if (!stricmp(item, "tempo"))
    {
        unsigned __int16 tempo = atoi(val);
        if (!tempo) return 1;
        if (MP4SetMetadataTempo(file, tempo)) return 1;
    }
    else if (!stricmp(item, "artist"))
    {
        if (MP4SetMetadataArtist(file, val)) return 1;
    }
    else if (!stricmp(item, "writer"))
    {
        if (MP4SetMetadataWriter(file, val)) return 1;
    }
    else if (!stricmp(item, "title"))
    {
        if (MP4SetMetadataName(file, val)) return 1;
    }
    else if (!stricmp(item, "album"))
    {
        if (MP4SetMetadataAlbum(file, val)) return 1;
    }
    else if (!stricmp(item, "date") || !stricmp(item, "year"))
    {
        if (MP4SetMetadataYear(file, val)) return 1;
    }
    else if (!stricmp(item, "comment"))
    {
        if (MP4SetMetadataComment(file, val)) return 1;
    }
    else if (!stricmp(item, "genre"))
    {
        if (MP4SetMetadataGenre(file, val)) return 1;
    }
    else if (!stricmp(item, "tool"))
    {
        if (MP4SetMetadataTool(file, val)) return 1;
    }
    else
    {
        if (MP4SetMetadataFreeForm(file, (char *)item, (u_int8_t *)val, (u_int32_t)strlen(val) + 1)) return 1;
    }

    return 0;
}
Ejemplo n.º 5
0
DWORD CTag_Mp4::Save(LPCTSTR szFileName)
{
    DWORD dwWin32errorCode = ERROR_SUCCESS;
    if(!m_bEnable)
    {
        return -1;
    }

    char *pFileName = TstrToDataAlloc(szFileName, -1, NULL, DTC_CODE_UTF8);
    if (pFileName == NULL) {
        return -1;
    }
    MP4FileHandle mp4file = MP4Modify(pFileName);
    free(pFileName);
    if(mp4file == MP4_INVALID_FILE_HANDLE)
    {
        return -1;
    }

#ifdef USE_OLD_TAG_API
    if(m_strMetadata_Name.GetLength())
    {
        char *buf = TstrToDataAlloc(m_strMetadata_Name, -1, NULL, DTC_CODE_UTF8);
        if (buf != NULL) {
            MP4SetMetadataName(mp4file,buf);
            free(buf);
        }
    }
    else
    {
        MP4DeleteMetadataName(mp4file);
    }

    if(m_strMetadata_Artist.GetLength())
    {
        char *buf = TstrToDataAlloc(m_strMetadata_Artist, -1, NULL, DTC_CODE_UTF8);
        if (buf != NULL) {
            MP4SetMetadataArtist(mp4file,buf);
            free(buf);
        }
    }
    else
    {
        MP4DeleteMetadataArtist(mp4file);
    }

    if(m_strMetadata_Album.GetLength())
    {
        char *buf = TstrToDataAlloc(m_strMetadata_Album, -1, NULL, DTC_CODE_UTF8);
        if (buf != NULL) {
            MP4SetMetadataAlbum(mp4file,buf);
            free(buf);
        }
    }
    else
    {
        MP4DeleteMetadataAlbum(mp4file);
    }

    if(m_strMetadata_Group.GetLength())
    {
        char *buf = TstrToDataAlloc(m_strMetadata_Group, -1, NULL, DTC_CODE_UTF8);
        if (buf != NULL) {
            MP4SetMetadataGrouping(mp4file,buf);
            free(buf);
        }
    }
    else
    {
        MP4DeleteMetadataGrouping(mp4file);
    }

    if(m_strMetadata_Composer.GetLength())
    {
        char *buf = TstrToDataAlloc(m_strMetadata_Composer, -1, NULL, DTC_CODE_UTF8);
        if (buf != NULL) {
            MP4SetMetadataWriter(mp4file,buf);
            free(buf);
        }
    }
    else
    {
        MP4DeleteMetadataWriter(mp4file);
    }

    if(m_strMetadata_Genre.GetLength())
    {
        char *buf = TstrToDataAlloc(m_strMetadata_Genre, -1, NULL, DTC_CODE_UTF8);
        if (buf != NULL) {
            MP4SetMetadataGenre(mp4file,buf);
            free(buf);
        }
    }
    else
    {
        MP4DeleteMetadataGenre(mp4file);
    }

    if((m_iMetadata_Track1 == -1) && (m_iMetadata_Track2 == -1))
    {
        MP4DeleteMetadataTrack(mp4file);
    }
    else if(m_iMetadata_Track1 == -1)
    {
        MP4SetMetadataTrack(mp4file,0,m_iMetadata_Track2);
    }
    else if(m_iMetadata_Track2 == -1)
    {
        MP4SetMetadataTrack(mp4file,m_iMetadata_Track1,0);
    }
    else
    {
        MP4SetMetadataTrack(mp4file,m_iMetadata_Track1,m_iMetadata_Track2);
    }

    if((m_iMetadata_Disc1 == -1) && (m_iMetadata_Disc2 == -1))
    {
        MP4DeleteMetadataDisk(mp4file);
    }
    else if(m_iMetadata_Disc1 == -1)
    {
        MP4SetMetadataDisk(mp4file,0,m_iMetadata_Disc2);
    }
    else if(m_iMetadata_Disc2 == -1)
    {
        MP4SetMetadataDisk(mp4file,m_iMetadata_Disc1,0);
    }
    else
    {
        MP4SetMetadataDisk(mp4file,m_iMetadata_Disc1,m_iMetadata_Disc2);
    }

    if(m_iMetadata_Tempo == -1)
    {
        MP4DeleteMetadataTempo(mp4file);
    }
    else
    {
        MP4SetMetadataTempo(mp4file,m_iMetadata_Tempo);
    }

    if(m_strMetadata_Year.GetLength())
    {
        char *buf = TstrToDataAlloc(m_strMetadata_Year, -1, NULL, DTC_CODE_UTF8);
        if (buf != NULL) {
            MP4SetMetadataYear(mp4file,buf);
            free(buf);
        }
    }
    else
    {
        MP4DeleteMetadataYear(mp4file);
    }

    if(m_iMetadata_Compilation != -1)
    {
        MP4SetMetadataCompilation(mp4file,1);
    }
    else
    {
        MP4DeleteMetadataCompilation(mp4file);
    }

    if(m_strMetadata_Comment.GetLength())
    {
        char *buf = TstrToDataAlloc(m_strMetadata_Comment, -1, NULL, DTC_CODE_UTF8);
        if (buf != NULL) {
            MP4SetMetadataComment(mp4file,buf);
            free(buf);
        }
    }
    else
    {
        MP4DeleteMetadataComment(mp4file);
    }

    if(m_strMetadata_Tool.GetLength())
    {
        char *buf = TstrToDataAlloc(m_strMetadata_Tool, -1, NULL, DTC_CODE_UTF8);
        if (buf != NULL) {
            MP4SetMetadataTool(mp4file,buf);
            free(buf);
        }
    }
    else
    {
        MP4DeleteMetadataTool(mp4file);
    }
#else
    const MP4Tags* tags = MP4TagsAlloc();

    if(tags)
    {
        MP4TagsFetch(tags, mp4file);

        if(m_strMetadata_Name.GetLength())
        {
            char *buf = TstrToDataAlloc(m_strMetadata_Name, -1, NULL, DTC_CODE_UTF8);
            if (buf != NULL) {
                MP4TagsSetName(tags, buf);
                free(buf);
            }
        }
        else
        {
            MP4TagsSetName(tags, NULL);
        }

        if(m_strMetadata_Artist.GetLength())
        {
            char *buf = TstrToDataAlloc(m_strMetadata_Artist, -1, NULL, DTC_CODE_UTF8);
            if (buf != NULL) {
                MP4TagsSetArtist(tags, buf);
                free(buf);
            }
        }
        else
        {
            MP4TagsSetArtist(tags, NULL);
        }

        if(m_strMetadata_Album.GetLength())
        {
            char *buf = TstrToDataAlloc(m_strMetadata_Album, -1, NULL, DTC_CODE_UTF8);
            if (buf != NULL) {
                MP4TagsSetAlbum(tags, buf);
                free(buf);
            }
        }
        else
        {
            MP4TagsSetAlbum(tags, NULL);
        }

        if(m_strMetadata_Group.GetLength())
        {
            char *buf = TstrToDataAlloc(m_strMetadata_Group, -1, NULL, DTC_CODE_UTF8);
            if (buf != NULL) {
                MP4TagsSetGrouping(tags, buf);
                free(buf);
            }
        }
        else
        {
            MP4TagsSetGrouping(tags, NULL);
        }

        if(m_strMetadata_Composer.GetLength())
        {
            char *buf = TstrToDataAlloc(m_strMetadata_Composer, -1, NULL, DTC_CODE_UTF8);
            if (buf != NULL) {
                MP4TagsSetComposer(tags, buf);
                free(buf);
            }
        }
        else
        {
            MP4TagsSetComposer(tags, NULL);
        }

        if(m_strMetadata_Genre.GetLength())
        {
            char *buf = TstrToDataAlloc(m_strMetadata_Genre, -1, NULL, DTC_CODE_UTF8);
            if (buf != NULL) {
                MP4TagsSetGenre(tags, buf);
                free(buf);
            }
        }
        else
        {
            MP4TagsSetGenre(tags, NULL);
        }

        if((m_iMetadata_Track1 == -1) && (m_iMetadata_Track2 == -1))
        {
            MP4TagsSetTrack(tags, NULL);
        }
        else
        {
            MP4TagTrack track;
            track.index = (m_iMetadata_Track1 == -1) ? 0 : m_iMetadata_Track1;
            track.total = (m_iMetadata_Track2 == -1) ? 0 : m_iMetadata_Track2;
            MP4TagsSetTrack(tags, &track);
        }

        if((m_iMetadata_Disc1 == -1) && (m_iMetadata_Disc2 == -1))
        {
            MP4TagsSetDisk(tags, NULL);
        }
        else
        {
            MP4TagDisk disk;
            disk.index = (m_iMetadata_Disc1 == -1) ? 0 : m_iMetadata_Disc1;
            disk.total = (m_iMetadata_Disc2 == -1) ? 0 : m_iMetadata_Disc2;
            MP4TagsSetDisk(tags, &disk);
        }

        if(m_iMetadata_Tempo == -1)
        {
            MP4TagsSetTempo(tags, NULL);
        }
        else
        {
            uint16_t tempo = m_iMetadata_Tempo;
            MP4TagsSetTempo(tags, &tempo);
        }

        if(m_strMetadata_Year.GetLength())
        {
            char *buf = TstrToDataAlloc(m_strMetadata_Year, -1, NULL, DTC_CODE_UTF8);
            if (buf != NULL) {
                MP4TagsSetReleaseDate(tags, buf);
                free(buf);
            }
        }
        else
        {
            MP4TagsSetReleaseDate(tags, NULL);
        }

        if(m_iMetadata_Compilation != -1)
        {
            uint8_t compilation = 1;
            MP4TagsSetCompilation(tags, &compilation);
        }
        else
        {
            MP4TagsSetCompilation(tags, NULL);
        }

        if(m_strMetadata_Comment.GetLength())
        {
            char *buf = TstrToDataAlloc(m_strMetadata_Comment, -1, NULL, DTC_CODE_UTF8);
            if (buf != NULL) {
                MP4TagsSetComments(tags, buf);
                free(buf);
            }
        }
        else
        {
            MP4TagsSetComments(tags, NULL);
        }

        if(m_strMetadata_Tool.GetLength())
        {
            char *buf = TstrToDataAlloc(m_strMetadata_Tool, -1, NULL, DTC_CODE_UTF8);
            if (buf != NULL) {
                MP4TagsSetEncodingTool(tags, buf);
                free(buf);
            }
        }
        else
        {
            MP4TagsSetEncodingTool(tags, NULL);
        }

        MP4TagsStore(tags, mp4file);
        MP4TagsFree(tags);
    }
#endif

    MP4Close(mp4file);

    return dwWin32errorCode;
}
Ejemplo n.º 6
0
bool MP4::File::save()
{
    MP4Close(mp4file);

    MP4FileHandle handle = MP4Modify(name());
    if(handle == MP4_INVALID_FILE_HANDLE)
    {
        mp4file = MP4Read(name());
        return false;
    }

#ifdef MP4V2_HAS_WRITE_BUG
    /* according to gtkpod we have to delete all meta data before modifying it,
       save the stuff we would not touch */

    // need to fetch/rewrite this only if we aren't going to anyway
    uint8_t compilation = 0;
    bool has_compilation = mp4tag->compilation() == MP4::Tag::Undefined ? MP4GetMetadataCompilation(handle, &compilation) : false;

    char *tool = NULL;
    MP4GetMetadataTool(handle, &tool);

    MP4MetadataDelete(handle);
#endif



#define setmeta(val, tag) \
    if(mp4tag->val().isNull()) { \
        /*MP4DeleteMetadata##tag(handle);*/ \
        MP4SetMetadata##tag(handle, ""); \
    } else { \
        MP4SetMetadata##tag(handle, mp4tag->val().toCString(true)); \
    }

    setmeta(title, Name);
    setmeta(artist, Artist);
    setmeta(album, Album);
    setmeta(comment, Comment);
    setmeta(genre, Genre);

    char buf[100] = "";
    if(mp4tag->year())
        snprintf(buf, sizeof(buf), "%u", mp4tag->year());
    MP4SetMetadataYear(handle, buf);
    u_int16_t t1, t2;
    MP4GetMetadataTrack(handle, &t1, &t2);
    MP4SetMetadataTrack(handle, mp4tag->track(), t2);
    if(mp4tag->bpm() != 0)
        MP4SetMetadataTempo(handle, mp4tag->bpm());
    if(mp4tag->compilation() != MP4::Tag::Undefined) {
        MP4SetMetadataCompilation(handle, mp4tag->compilation());
    }

    MP4SetMetadataCoverArt(handle, mp4tag->cover().size() ? const_cast<u_int8_t *>( reinterpret_cast<const u_int8_t *>( mp4tag->cover().data() ) ) : 0, mp4tag->cover().size());

#ifdef MP4V2_HAS_WRITE_BUG
    // set the saved data again

    if(has_compilation)
        MP4SetMetadataCompilation(handle, compilation);
    if(tool)
    {
        MP4SetMetadataTool(handle, tool);
        free(tool);
    }
#endif

    MP4Close(handle);

    mp4file = MP4Read(name());
    if(mp4file == MP4_INVALID_FILE_HANDLE)
    {
        fprintf(stderr, "reopen failed\n");
        return false;
    }

    return true;
}