📄 audio.c
字号:
#include "amp.h"
#include <sys/types.h>
#include <sys/stat.h>
#ifndef __BEOS__
#include <sys/uio.h>
#endif
#include <sys/socket.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define AUDIO
#include "audio.h"
#include "formats.h"
#include "getbits.h"
#include "huffman.h"
#include "layer2.h"
#include "layer3.h"
#include "position.h"
#include "rtbuf.h"
#include "transform.h"
#include "controldata.h"
#include "guicontrol.h"
#ifndef __BEOS__
typedef int bool;
#endif
void statusDisplay(struct AUDIO_HEADER *header, int frameNo)
{
int minutes,seconds;
if ((A_SHOW_CNT || A_SHOW_TIME) && !(frameNo%10))
msg("\r");
if (A_SHOW_CNT && !(frameNo%10) ) {
msg("{ %d } ",frameNo);
}
if (A_SHOW_TIME && !(frameNo%10)) {
seconds=frameNo*1152/t_sampling_frequency[header->ID][header->sampling_frequency];
minutes=seconds/60;
seconds=seconds % 60;
msg("[%d:%02d]",minutes,seconds);
}
if (A_SHOW_CNT || A_SHOW_TIME)
fflush(stderr);
}
int decodeMPEG(void)
{
struct AUDIO_HEADER header;
int cnt,g,snd_eof;
uid_t my_uid = getuid();
#ifdef LINUX_REALTIME
set_realtime_priority();
setreuid(my_uid, my_uid);
prefetch_initial_fill();
#endif /* LINUX_REALTIME */
initialise_globals();
#ifndef LINUX_REALTIME
if (A_FORMAT_WAVE) wav_begin();
#endif /* LINUX_REALTIME */
if ((g=gethdr(&header))!=0) {
report_header_error(g);
return -1;
}
if (header.protection_bit==0) getcrc();
#ifdef LINUX_REALTIME
if (setup_fancy_audio(&header)!=0) {
warn("Cannot set up direct-to-DMA audio. Exiting\n");
return -1;
}
#else
if (setup_audio(&header)!=0) {
warn("Cannot set up audio. Exiting\n");
return -1;
}
#endif /* LINUX_REALTIME */
show_header(&header);
if (header.layer==1) {
if (layer3_frame(&header,cnt)) {
warn(" error. blip.\n");
return -1;
}
} else if (header.layer==2)
if (layer2_frame(&header,cnt)) {
warn(" error. blip.\n");
return -1;
}
#ifdef LINUX_REALTIME
if (start_fancy_audio(&header)!=0) {
warn("Cannot start direct-to-DMA audio. Exiting\n");
return -1;
}
#endif /* LINUX_REALTIME */
/*
* decoder loop **********************************
*/
snd_eof=0;
cnt=0;
while (!snd_eof) {
while (!snd_eof && ready_audio()) {
if ((g=gethdr(&header))!=0) {
report_header_error(g);
#ifdef LINUX_REALTIME
cleanup_fancy_audio();
#else
if (g==GETHDR_EOF && A_FORMAT_WAVE) wav_end(&header);
#endif /* LINUX_REALTIME */
snd_eof=1;
break;
}
if (header.protection_bit==0) getcrc();
statusDisplay(&header,cnt);
if (header.layer==1) {
if (layer3_frame(&header,cnt)) {
warn(" error. blip.\n");
return -1;
}
} else if (header.layer==2)
if (layer2_frame(&header,cnt)) {
warn(" error. blip.\n");
return -1;
}
cnt++;
}
#ifdef LINUX_REALTIME
if (block_fancy_audio(snd_eof)!=0) {
warn("Problems with direct-to-DMA audio\n");
return -1;
}
#endif
}
#ifdef LINUX_REALTIME
if (stop_fancy_audio()!=0) {
warn("Cannot stop direct-to-DMA audio. Exiting\n");
return -1;
}
#endif
return 0;
}
int main(int argc,char **argv)
{
int argPos;
argPos=args(argc,argv); /* process command line arguments */
initialise_decoder(); /* initialise decoder */
if (argc == 1) { /* Start amp as a GUI backend. */
A_QUIET = TRUE; /* TODO: change this to A_GUI_CONTROLLED */
#ifndef OS_SunOS
gui_control();
#endif
} else {
if (A_AUDIO_PLAY) { /* play each specified file */
if (argPos<argc)
for(;argPos<argc;argPos++) {
#ifdef LINUX_REALTIME
if (geteuid() != 0)
die("effective UID not root, cannot use realtime buffering\n");
rt_play(argv[argPos]);
#else /* LINUX_REALTIME */
play(argv[argPos],0);
#endif /* LINUX_REALTIME */
}
else
displayUsage();
} else { /* convert the file to some format */
if ((argPos+2)==argc)
play(argv[argPos],argv[argPos+1]);
else {
warn("Invalid number of parameters\n");
displayUsage();
die("");
}
}
msg("\nThank you for using amp!\n");
exit(0);
}
exit(0);
}
/* call this once at the beginning
*/
void initialise_decoder(void)
{
premultiply();
imdct_init();
calculate_t43();
}
/* call this before each file is played
*/
void initialise_globals(void)
{
append=data=nch=0;
f_bdirty=TRUE;
bclean_bytes=0;
memset(s,0,sizeof s);
memset(res,0,sizeof res);
}
void report_header_error(int err)
{
switch (err) {
case GETHDR_ERR: die("error reading mpeg bitstream. exiting.\n");
break;
case GETHDR_NS : warn("this is a file in MPEG 2.5 format, which is not defined\n");
warn("by ISO/MPEG. It is \"a special Fraunhofer format\".\n");
warn("amp does not support this format. sorry.\n");
break;
case GETHDR_FL1: warn("ISO/MPEG layer 1 is not supported by amp (yet).\n");
break;
case GETHDR_FF : warn("free format bitstreams are not supported. sorry.\n");
break;
case GETHDR_SYN: warn("oops, we're out of sync.\n");
break;
case GETHDR_EOF:
default: ; /* some stupid compilers need the semicolon */
}
}
/* TODO: there must be a check here to see if the audio device has been opened
* successfuly. This is a bitch because it requires all 6 or 7 OS-specific functions
* to be changed. Is anyone willing to do this at all???
*/
int setup_audio(struct AUDIO_HEADER *header)
{
if (A_AUDIO_PLAY)
if (AUDIO_BUFFER_SIZE==0)
audioOpen(t_sampling_frequency[header->ID][header->sampling_frequency],
(header->mode!=3 && !A_DOWNMIX),A_SET_VOLUME);
else
audioBufferOpen(t_sampling_frequency[header->ID][header->sampling_frequency],
(header->mode!=3 && !A_DOWNMIX),A_SET_VOLUME);
return 0;
}
void close_audio(void)
{
if (A_AUDIO_PLAY)
if (AUDIO_BUFFER_SIZE!=0)
audioBufferClose();
else
audioClose();
}
int ready_audio(void)
{
#ifdef LINUX_REALTIME
return ready_fancy_audio();
#else
return 1;
#endif
}
/* TODO: add some kind of error reporting here
*/
void play(char *inFileStr, char *outFileStr)
{
if (strcmp(inFileStr,"-")==0)
in_file=stdin;
else {
if ((in_file=fopen(inFileStr,"r"))==NULL) {
warn("Could not open file: %s\n",inFileStr);
return;
}
}
if (outFileStr) {
if (strcmp(outFileStr,"-")==0)
out_file=stdout;
else
if ((out_file=fopen(outFileStr,"w"))==NULL) {
warn("Could not write to file: %s\n",outFileStr);
return;
}
msg("Converting: %s\n",inFileStr);
}
if (A_AUDIO_PLAY)
msg("Playing: %s\n",inFileStr);
/*
*
*/
decodeMPEG();
close_audio();
fclose(in_file);
if (!A_AUDIO_PLAY) fclose(out_file);
msg("\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -