diff options
author | Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | 2020-06-09 17:37:40 +0100 |
---|---|---|
committer | Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | 2020-06-09 17:37:40 +0100 |
commit | f25f654d6ca981efdbc9aa2c11f11422c9fe6c01 (patch) | |
tree | 582cbf948c6fba11ffe8f9bae4ef7089fc50d512 | |
parent | 31a0a4c57026cd4ee682e4c5eccfaba153cd8f03 (diff) |
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-rw-r--r-- | src/utils-lgpl/fcplay.c | 228 |
1 files changed, 221 insertions, 7 deletions
diff --git a/src/utils-lgpl/fcplay.c b/src/utils-lgpl/fcplay.c index 83d48a0..991ca43 100644 --- a/src/utils-lgpl/fcplay.c +++ b/src/utils-lgpl/fcplay.c @@ -77,6 +77,10 @@ static void usage(void) void play_samples(char *name, unsigned int card, unsigned int device, unsigned long buffer_size, unsigned int frag, unsigned long codec_id); +void play_gapless_samples(char **names, int start_idx, int fcount, unsigned int card, unsigned int device, + unsigned long buffer_size, unsigned int frag, + unsigned long codec_id); + static int print_time(struct compress *compress) { @@ -96,7 +100,7 @@ int main(int argc, char **argv) { char *file; unsigned long buffer_size = 0; - int c, i; + int c, i, gapless = 0; unsigned int card = 0, device = 0, frag = 0; unsigned int codec_id = SND_AUDIOCODEC_MP3; @@ -104,7 +108,7 @@ int main(int argc, char **argv) usage(); verbose = 0; - while ((c = getopt(argc, argv, "hvb:f:c:d:I:")) != -1) { + while ((c = getopt(argc, argv, "hvg:b:f:c:d:I:")) != -1) { switch (c) { case 'h': usage(); @@ -143,6 +147,9 @@ int main(int argc, char **argv) case 'v': verbose = 1; break; + case 'g': + gapless = 1; + break; default: exit(EXIT_FAILURE); } @@ -150,9 +157,13 @@ int main(int argc, char **argv) if (optind >= argc) usage(); - file = argv[optind]; - - play_samples(file, card, device, buffer_size, frag, codec_id); + if (gapless) { + play_gapless_samples(argv, optind, argc - optind, card, + device, buffer_size, frag, codec_id); + } else { + file = argv[optind]; + play_samples(file, card, device, buffer_size, frag, codec_id); + } fprintf(stderr, "Finish Playing.... Close Normally\n"); exit(EXIT_SUCCESS); @@ -187,7 +198,8 @@ static int get_codec_id(int codec_id) } } -static int parse_file(char *file, struct snd_codec *codec) +static int parse_file(char *file, struct snd_codec *codec, + struct compr_gapless_mdata *mdata) { AVFormatContext *ctx = NULL; AVStream *stream; @@ -238,6 +250,17 @@ static int parse_file(char *file, struct snd_codec *codec) codec->level = 0; codec->rate_control = 0; codec->ch_mode = 0; + + if (mdata) { + // mdata->encoder_delay = ctx->initial_padding; + mdata->encoder_padding = stream->first_discard_sample;//#codec->trailing_padding; + printf("DEBUG:: %s: %d\n", __func__, mdata->encoder_padding); + printf("DEBUG:: %s: %ld\n", __func__, stream->start_skip_samples); + printf("DEBUG:: %s: %ld\n", __func__, stream->last_discard_sample); + printf("DEBUG:: %s: %ld\n", __func__, stream->start_skip_samples); + printf("DEBUG:: %s: %ld\n", __func__, stream->start_skip_samples); + } + filled = 1; if (codec->id == SND_AUDIOCODEC_FLAC) { @@ -311,7 +334,7 @@ void play_samples(char *name, unsigned int card, unsigned int device, memset(&codec, 0, sizeof(codec)); memset(&config, 0, sizeof(config)); - parse_file(name, &codec); + parse_file(name, &codec, NULL); config.codec = &codec; @@ -394,3 +417,194 @@ FILE_EXIT: printf("%s: exit failure\n", __func__); exit(EXIT_FAILURE); } + +void play_gapless_samples(char **names, int start_idx, int fcount, unsigned int card, unsigned int device, + unsigned long buffer_size, unsigned int frag, + unsigned long codec_id) +{ + struct compr_config config; + struct compr_gapless_mdata mdata; + struct snd_codec codec; + struct compress *compress; + FILE *file; + char *buffer; + int size, num_read, wrote; + int test_loop = 10; + int file_idx = 0; + int rc = 0; + char *name; + + + if (verbose) + printf("%s: Playing Gapless for %d files\n", __func__, fcount); + + memset(&codec, 0, sizeof(codec)); + memset(&config, 0, sizeof(config)); + + name = names[start_idx + file_idx]; + printf("DEBUG:%s: %d %s file \n", __func__, __LINE__, name); + parse_file(name, &codec, &mdata); + file = fopen(name, "rb"); + if (!file) { + fprintf(stderr, "Unable to open file '%s'\n", name); + exit(EXIT_FAILURE); + } + + + config.codec = &codec; + + compress = compress_open(card, device, COMPRESS_IN, &config); + if (!compress || !is_compress_ready(compress)) { + fprintf(stderr, "Unable to open Compress device %d:%d\n", + card, device); + fprintf(stderr, "ERR: %s\n", compress_get_error(compress)); + goto FILE_EXIT; + }; + if (verbose) + printf("%s: Opened compress device\n", __func__); + + size = config.fragment_size; + buffer = malloc(size * config.fragments); + if (!buffer) { + fprintf(stderr, "Unable to allocate %d bytes\n", size); + goto COMP_EXIT; + } + mdata.encoder_delay = 20* 2048; + mdata.encoder_padding = 10* 1024; + + compress_set_gapless_metadata(compress, &mdata); + + + /* we will write frag fragment_size and then start */ + num_read = fread(buffer, 1, size * config.fragments, file); + if (num_read > 0) { + if (verbose) + printf("%s: Doing first buffer write of %d\n", __func__, num_read); + wrote = compress_write(compress, buffer, num_read); + if (wrote < 0) { + fprintf(stderr, "Error %d playing sample\n", wrote); + fprintf(stderr, "ERR: %s\n", compress_get_error(compress)); + goto BUF_EXIT; + } + if (wrote != num_read) { + /* TODO: Buufer pointer needs to be set here */ + fprintf(stderr, "We wrote %d, DSP accepted %d\n", num_read, wrote); + } + } + + compress_start(compress); + if (verbose) + printf("%s: You should hear audio NOW!!!\n", __func__); + + + do { + if (verbose) + printf("%s: gapless loop %d\n", __func__, test_loop); + + printf("DEBUG: %s: %d \n", __func__, __LINE__); + if (file_idx != 0) { + name = names[start_idx + file_idx]; + printf("DEBUG: %s: %d \n", __func__, __LINE__); + file = fopen(name, "rb"); + if (!file) { + fprintf(stderr, "Unable to open file '%s'\n", name); + goto TRACK_EXIT; + } + + printf("DEBUG: %s: %d \n", __func__, __LINE__); + parse_file(name, &codec, &mdata); + + printf("DEBUG: %s: %d \n", __func__, __LINE__); + rc = compress_next_track(compress); + if (rc) { + fprintf(stderr, "Failed to set next track (%d)\n", rc); + goto TRACK_EXIT; + } + + printf("DEBUG: %s: %d \n", __func__, __LINE__); + //FIXME + mdata.encoder_delay = 2048; + mdata.encoder_padding = 1024; + + printf("DEBUG: %s: %d \n", __func__, __LINE__); + rc = compress_set_gapless_metadata(compress, &mdata); + if (rc) { + fprintf(stderr, "Failed to set gapless metadata (%d)\n", rc); + goto TRACK_EXIT; + } + + printf("DEBUG: %s: %d \n", __func__, __LINE__); + rc = compress_set_codec_params(compress, &codec); + if (rc) { + fprintf(stderr, "Failed to set codec params (%d)\n", rc); + goto TRACK_EXIT; + } + + printf("DEBUG: %s: %d \n", __func__, __LINE__); + rc = compress_partial_drain(compress); + if (rc) { + fprintf(stderr, "Failed to partial drain (%d)\n", rc); + goto TRACK_EXIT; + } + printf("DEBUG: %s: %d \n", __func__, __LINE__); + } + + printf("Playing file %s On Card %u device %u, with buffer of %lu bytes\n", + name, card, device, buffer_size); + printf("Format %u Channels %u, %u Hz, Bit Rate %d\n", + codec.id, codec.ch_in, codec.sample_rate, codec.bit_rate); + + do { + num_read = fread(buffer, 1, size, file); + if (num_read > 0) { + wrote = compress_write(compress, buffer, num_read); + if (wrote < 0) { + fprintf(stderr, "Error playing sample\n"); + fprintf(stderr, "ERR: %s\n", compress_get_error(compress)); + goto BUF_EXIT; + } + if (wrote != num_read) { + /* TODO: Buffer pointer needs to be set here */ + fprintf(stderr, "We wrote %d, DSP accepted %d\n", num_read, wrote); + } + if (verbose) { + print_time(compress); + printf("%s: wrote %d\n", __func__, wrote); + } + } + } while (num_read > 0); + + file_idx++; + + if (file_idx == fcount) { + /* Finished playing all the files.*/ + rc = compress_drain(compress); + if (rc) { + fprintf(stderr, "Failed to drain (%d)\n", rc); + goto TRACK_EXIT; + } + } + + fclose(file); + printf("File idx vs fcount %d vs %d \n", file_idx, fcount); + + } while (file_idx < fcount); + + if (verbose) + printf("%s: exit success\n", __func__); + + free(buffer); + compress_close(compress); + return; + +TRACK_EXIT: + fclose(file); +BUF_EXIT: + free(buffer); +COMP_EXIT: + compress_close(compress); +FILE_EXIT: + if (verbose) + printf("%s: exit failure\n", __func__); + exit(EXIT_FAILURE); +} |