mirror of
https://github.com/alsa-project/alsa-tools.git
synced 2025-10-31 22:25:34 -04:00
Added better period_time setup to the ALSA output code.
Added end-of-file checking to the libac3.
This commit is contained in:
parent
3d1998857a
commit
c40c3b5623
6 changed files with 47 additions and 23 deletions
|
|
@ -41,10 +41,11 @@ uint_32 current_word;
|
||||||
|
|
||||||
ssize_t (*bitstream_fill_buffer)(uint_8**,uint_8**);
|
ssize_t (*bitstream_fill_buffer)(uint_8**,uint_8**);
|
||||||
|
|
||||||
uint_8 bitstream_get_byte(void)
|
int bitstream_get_byte(void)
|
||||||
{
|
{
|
||||||
if(chunk_start == chunk_end)
|
if(chunk_start == chunk_end)
|
||||||
bitstream_fill_buffer(&chunk_start,&chunk_end);
|
if (bitstream_fill_buffer(&chunk_start,&chunk_end) <= 0)
|
||||||
|
return EOF;
|
||||||
|
|
||||||
return (*chunk_start++);
|
return (*chunk_start++);
|
||||||
}
|
}
|
||||||
|
|
@ -54,7 +55,7 @@ uint_8 *bitstream_get_buffer_start(void)
|
||||||
return buffer_start;
|
return buffer_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
bitstream_buffer_frame(uint_32 frame_size)
|
bitstream_buffer_frame(uint_32 frame_size)
|
||||||
{
|
{
|
||||||
uint_32 bytes_read;
|
uint_32 bytes_read;
|
||||||
|
|
@ -67,7 +68,8 @@ bitstream_buffer_frame(uint_32 frame_size)
|
||||||
if(chunk_start > chunk_end)
|
if(chunk_start > chunk_end)
|
||||||
printf("argh!\n");
|
printf("argh!\n");
|
||||||
if(chunk_start == chunk_end)
|
if(chunk_start == chunk_end)
|
||||||
bitstream_fill_buffer(&chunk_start,&chunk_end);
|
if (bitstream_fill_buffer(&chunk_start,&chunk_end) <= 0)
|
||||||
|
return EOF;
|
||||||
|
|
||||||
num_bytes = chunk_end - chunk_start;
|
num_bytes = chunk_end - chunk_start;
|
||||||
|
|
||||||
|
|
@ -84,7 +86,8 @@ bitstream_buffer_frame(uint_32 frame_size)
|
||||||
buffer_start = buffer;
|
buffer_start = buffer;
|
||||||
buffer_end = buffer + frame_size;
|
buffer_end = buffer + frame_size;
|
||||||
|
|
||||||
bits_left = 0;
|
bits_left = 0;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,10 +52,10 @@ extern uint_32 current_word;
|
||||||
|
|
||||||
void bitstream_init(ssize_t(*fill_function)(uint_8**,uint_8**));
|
void bitstream_init(ssize_t(*fill_function)(uint_8**,uint_8**));
|
||||||
|
|
||||||
uint_8 bitstream_get_byte(void);
|
int bitstream_get_byte(void);
|
||||||
|
|
||||||
uint_8 *bitstream_get_buffer_start(void);
|
uint_8 *bitstream_get_buffer_start(void);
|
||||||
void bitstream_buffer_frame(uint_32 frame_size);
|
int bitstream_buffer_frame(uint_32 frame_size);
|
||||||
|
|
||||||
uint_32 bitstream_get_bh(uint_32 num_bits);
|
uint_32 bitstream_get_bh(uint_32 num_bits);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,8 @@ ac3_decode_frame(void)
|
||||||
uint_32 i;
|
uint_32 i;
|
||||||
|
|
||||||
//find a syncframe and parse
|
//find a syncframe and parse
|
||||||
parse_syncinfo(&syncinfo);
|
if (parse_syncinfo(&syncinfo) < 0)
|
||||||
|
return NULL;
|
||||||
if(error_flag)
|
if(error_flag)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
#include "ac3.h"
|
#include "ac3.h"
|
||||||
#include "ac3_internal.h"
|
#include "ac3_internal.h"
|
||||||
|
|
||||||
|
|
@ -114,9 +115,10 @@ parse_syncinfo_data(syncinfo_t *syncinfo, uint_8 *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse a syncinfo structure, minus the sync word */
|
/* Parse a syncinfo structure, minus the sync word */
|
||||||
void
|
int
|
||||||
parse_syncinfo(syncinfo_t *syncinfo)
|
parse_syncinfo(syncinfo_t *syncinfo)
|
||||||
{
|
{
|
||||||
|
int byte, idx;
|
||||||
uint_8 data[3];
|
uint_8 data[3];
|
||||||
uint_16 sync_word = 0;
|
uint_16 sync_word = 0;
|
||||||
uint_32 time_out = 1<<16;
|
uint_32 time_out = 1<<16;
|
||||||
|
|
@ -128,7 +130,10 @@ parse_syncinfo(syncinfo_t *syncinfo)
|
||||||
//
|
//
|
||||||
while(time_out--)
|
while(time_out--)
|
||||||
{
|
{
|
||||||
sync_word = (sync_word << 8) + bitstream_get_byte();
|
byte = bitstream_get_byte();
|
||||||
|
if (byte < 0)
|
||||||
|
return -ENOENT;
|
||||||
|
sync_word = (sync_word << 8) + byte;
|
||||||
|
|
||||||
if(sync_word == 0x0b77)
|
if(sync_word == 0x0b77)
|
||||||
break;
|
break;
|
||||||
|
|
@ -138,14 +143,18 @@ parse_syncinfo(syncinfo_t *syncinfo)
|
||||||
// We need to read in the entire syncinfo struct (0x0b77 + 24 bits)
|
// We need to read in the entire syncinfo struct (0x0b77 + 24 bits)
|
||||||
// in order to determine how big the frame is
|
// in order to determine how big the frame is
|
||||||
//
|
//
|
||||||
data[0] = bitstream_get_byte();
|
for (idx = 0; idx < 3; idx++) {
|
||||||
data[1] = bitstream_get_byte();
|
byte = bitstream_get_byte();
|
||||||
data[2] = bitstream_get_byte();
|
if (byte < 0)
|
||||||
|
return -ENOENT;
|
||||||
|
data[idx] = byte;
|
||||||
|
}
|
||||||
|
|
||||||
parse_syncinfo_data(syncinfo, data);
|
parse_syncinfo_data(syncinfo, data);
|
||||||
|
|
||||||
// Buffer the entire syncframe
|
// Buffer the entire syncframe
|
||||||
bitstream_buffer_frame(syncinfo->frame_size * 2 - 5);
|
if (bitstream_buffer_frame(syncinfo->frame_size * 2 - 5) < 0)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
// Check the crc over the entire frame
|
// Check the crc over the entire frame
|
||||||
crc_init();
|
crc_init();
|
||||||
|
|
@ -159,11 +168,12 @@ parse_syncinfo(syncinfo_t *syncinfo)
|
||||||
{
|
{
|
||||||
error_flag = 1;
|
error_flag = 1;
|
||||||
fprintf(stderr,"** CRC failed - skipping frame **\n");
|
fprintf(stderr,"** CRC failed - skipping frame **\n");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(ac3_config.flags & AC3_QUIET))
|
if (!(ac3_config.flags & AC3_QUIET))
|
||||||
stats_print_syncinfo(syncinfo);
|
stats_print_syncinfo(syncinfo);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void parse_syncinfo_data(syncinfo_t *syncinfo, uint_8 *data);
|
void parse_syncinfo_data(syncinfo_t *syncinfo, uint_8 *data);
|
||||||
void parse_syncinfo(syncinfo_t *syncinfo);
|
int parse_syncinfo(syncinfo_t *syncinfo);
|
||||||
void parse_audblk(bsi_t *bsi,audblk_t *audblk);
|
void parse_audblk(bsi_t *bsi,audblk_t *audblk);
|
||||||
void parse_bsi(bsi_t *bsi);
|
void parse_bsi(bsi_t *bsi);
|
||||||
void parse_auxdata(syncinfo_t *syncinfo);
|
void parse_auxdata(syncinfo_t *syncinfo);
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,8 @@ int output_open(output_t *output)
|
||||||
snd_pcm_hw_params_t *params;
|
snd_pcm_hw_params_t *params;
|
||||||
snd_pcm_sw_params_t *swparams;
|
snd_pcm_sw_params_t *swparams;
|
||||||
snd_pcm_sframes_t buffer_time;
|
snd_pcm_sframes_t buffer_time;
|
||||||
snd_pcm_sframes_t period_time;
|
snd_pcm_sframes_t period_time, tmp;
|
||||||
int err;
|
int err, step;
|
||||||
snd_pcm_hw_params_alloca(¶ms);
|
snd_pcm_hw_params_alloca(¶ms);
|
||||||
snd_pcm_sw_params_alloca(&swparams);
|
snd_pcm_sw_params_alloca(&swparams);
|
||||||
|
|
||||||
|
|
@ -112,11 +112,19 @@ int output_open(output_t *output)
|
||||||
fprintf(stderr, "Buffer time not available");
|
fprintf(stderr, "Buffer time not available");
|
||||||
goto __close;
|
goto __close;
|
||||||
}
|
}
|
||||||
period_time = 100000 * 2;
|
step = 2;
|
||||||
|
period_time = 10000 * 2;
|
||||||
do {
|
do {
|
||||||
period_time /= 2;
|
period_time /= 2;
|
||||||
period_time = snd_pcm_hw_params_set_period_time_near(pcm, params,
|
tmp = snd_pcm_hw_params_set_period_time_near(pcm, params,
|
||||||
|
period_time, 0);
|
||||||
|
if (tmp == period_time) {
|
||||||
|
period_time /= 3;
|
||||||
|
tmp = snd_pcm_hw_params_set_period_time_near(pcm, params,
|
||||||
period_time, 0);
|
period_time, 0);
|
||||||
|
if (tmp == period_time)
|
||||||
|
period_time = 10000 * 2;
|
||||||
|
}
|
||||||
if (period_time < 0) {
|
if (period_time < 0) {
|
||||||
fprintf(stderr, "Period time not available");
|
fprintf(stderr, "Period time not available");
|
||||||
goto __close;
|
goto __close;
|
||||||
|
|
@ -205,11 +213,13 @@ int output_play(sint_16* output_samples, uint_32 num_frames)
|
||||||
if (res == -EPIPE)
|
if (res == -EPIPE)
|
||||||
res = snd_pcm_prepare(pcm);
|
res = snd_pcm_prepare(pcm);
|
||||||
res = res < 0 ? res : snd_pcm_writei(pcm, (void *)output_samples, num_frames);
|
res = res < 0 ? res : snd_pcm_writei(pcm, (void *)output_samples, num_frames);
|
||||||
} while (res == -EPIPE);
|
if (res > 0) {
|
||||||
|
output_samples += out_config.channels * res;
|
||||||
|
num_frames -= res;
|
||||||
|
}
|
||||||
|
} while (res == -EPIPE || num_frames > 0);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
fprintf(stderr, "writei returned error: %s\n", snd_strerror(res));
|
fprintf(stderr, "writei returned error: %s\n", snd_strerror(res));
|
||||||
else if (res != num_frames)
|
|
||||||
fprintf(stderr, "writei retured %li (expected %li)\n", res, (long)(num_frames));
|
|
||||||
return res < 0 ? (int)res : 0;
|
return res < 0 ? (int)res : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue