Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[linux-dvb] Call for help: audio lost after PCM replay
Hi,
doing the mp3 stuff for vdr I have one big problem: after
stopping PCM replay I loose audio.
I took test_audio.c from the dvb package and modified it to
replay mp3 (you must have mpg123 in your path). Start with
test_audio <your-favorite_mp3>.
Restart the driver (now you should be watching N-TV). Start
test_audio. After it's finished you don't get back the audio from
N-TV.
I'm asking one of the developers if this is a bug or limitation
of the driver? May be I'm doing something wrong setting audio
back to live audio? Could one give me a hint, please?
TIA
/*
* test_audio.c - Test program for new API
*
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
* & Marcus Metzler <marcus@convergence.de>
for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#define _GNU_SOURCE
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <ost/dmx.h>
#include <ost/frontend.h>
#include <ost/sec.h>
#include <ost/audio.h>
int audioStop(int fd)
{
int ans;
if ( (ans = ioctl(fd,AUDIO_STOP,0) < 0)){
perror("AUDIO STOP: ");
return -1;
}
return 0;
}
int audioPlay(int fd)
{
int ans;
if ( (ans = ioctl(fd,AUDIO_PLAY) < 0)){
perror("AUDIO PLAY: ");
return -1;
}
return 0;
}
int audioPause(int fd)
{
int ans;
if ( (ans = ioctl(fd,AUDIO_PAUSE) < 0)){
perror("AUDIO PAUSE: ");
return -1;
}
return 0;
}
int audioContinue(int fd)
{
int ans;
if ( (ans = ioctl(fd,AUDIO_CONTINUE) < 0)){
perror("AUDIO CONTINUE: ");
return -1;
}
return 0;
}
int audioSelectSource(int fd, audioStreamSource_t source)
{
int ans;
if ( (ans = ioctl(fd,AUDIO_SELECT_SOURCE, source) < 0)){
perror("AUDIO SELECT SOURCE: ");
return -1;
}
return 0;
}
int audioSetMute(int fd, boolean state)
{
int ans;
if ( (ans = ioctl(fd,AUDIO_SET_MUTE, state) < 0)){
perror("AUDIO SET MUTE: ");
return -1;
}
return 0;
}
int audioClearBuffer(int fd)
{
int ans;
if ( (ans = ioctl(fd,AUDIO_CLEAR_BUFFER) < 0)){
perror("AUDIO CLEAR BUFFER: ");
return -1;
}
return 0;
}
int audioSetAVSync(int fd,boolean state)
{
int ans;
if ( (ans = ioctl(fd,AUDIO_SET_AV_SYNC, state) < 0)){
perror("AUDIO SET AV SYNC: ");
return -1;
}
return 0;
}
int audioGetStatus(int fd)
{
struct audioStatus stat;
int ans;
if ( (ans = ioctl(fd,AUDIO_GET_STATUS, &stat) < 0)){
perror("AUDIO GET STATUS: ");
return -1;
}
printf("Audio Status:\n");
printf(" Sync State : %s\n",
(stat.AVSyncState ? "SYNC" : "NO SYNC"));
printf(" Mute State : %s\n",
(stat.muteState ? "muted" : "not muted"));
printf(" Play State : ");
switch ((int)stat.playState){
case AUDIO_STOPPED:
printf("STOPPED (%d)\n",stat.playState);
break;
case AUDIO_PLAYING:
printf("PLAYING (%d)\n",stat.playState);
break;
case AUDIO_PAUSED:
printf("PAUSED (%d)\n",stat.playState);
break;
default:
printf("unknown (%d)\n",stat.playState);
break;
}
printf(" Stream Source : ");
switch((int)stat.streamSource){
case AUDIO_SOURCE_DEMUX:
printf("DEMUX (%d)\n",stat.streamSource);
break;
case AUDIO_SOURCE_MEMORY:
printf("MEMORY (%d)\n",stat.streamSource);
break;
default:
printf("unknown (%d)\n",stat.streamSource);
break;
}
printf(" Channel Select : ");
switch((int)stat.channelSelect){
case AUDIO_STEREO:
printf("Stereo (%d)\n",stat.channelSelect);
break;
case AUDIO_MONO_LEFT:
printf("Mono left(%d)\n",stat.channelSelect);
break;
case AUDIO_MONO_RIGHT:
printf("Mono right (%d)\n",stat.channelSelect);
break;
default:
printf("unknown (%d)\n",stat.channelSelect);
break;
}
printf(" Bypass Mode : %s\n",
(stat.bypassMode ? "ON" : "OFF"));
return 0;
}
#define PCM_FRAMESIZE 2000
struct PCMFrame {
unsigned char PESHeader[6];
unsigned char PCMHeader[10];
unsigned char Data[PCM_FRAMESIZE];
};
struct Frame {
int stat;
int size;
char *p;
struct PCMFrame frame;
}
init_frame(struct Frame *frame)
{
frame->stat=0;
frame->frame.PESHeader[0] = 0x00;
frame->frame.PESHeader[1] = 0x00;
frame->frame.PESHeader[2] = 0x01;
frame->frame.PESHeader[3] = 0xbd;
frame->frame.PCMHeader[0] = 0x80;
frame->frame.PCMHeader[1] = 0x00;
frame->frame.PCMHeader[2] = 0x00;
frame->frame.PCMHeader[3] = 0xa0; // substream ID
frame->frame.PCMHeader[4] = 0x00; // other stuff (see DVD specs), ignored by driver
frame->frame.PCMHeader[5] = 0x00;
frame->frame.PCMHeader[6] = 0x00;
frame->frame.PCMHeader[7] = 0x00;
frame->frame.PCMHeader[8] = 0x00;
frame->frame.PCMHeader[9] = 0x00;
}
#define NUM_FRAMES 48
play_file_audio(FILE *filefd, int fd)
{
struct Frame Frame[NUM_FRAMES], *frame;
int rf=0, wf=0;
int size, total=0, w, sleep;
for(w=0 ; w<NUM_FRAMES ; w++) init_frame(&Frame[w]);
while(!feof(filefd)) { // total<(4*1024*1024)) {
sleep=1;
frame=&Frame[rf];
if(!frame->stat) {
size = fread(frame->frame.Data, sizeof(unsigned char), sizeof(frame->frame.Data), filefd);
if(size<0) {
perror("pipe read:");
return;
}
if(size>0) {
size += sizeof(frame->frame.PCMHeader);
frame->frame.PESHeader[4] = (size >> 8) & 0xff;
frame->frame.PESHeader[5] = size & 0xff;
size += sizeof(frame->frame.PESHeader);
frame->size=size;
frame->p=(char *)&frame->frame;
frame->stat=1;
rf=(rf+1) % NUM_FRAMES;
total+=size;
sleep=0;
}
}
frame=&Frame[wf];
if(frame->stat) {
if(frame->size>0) {
size=write(fd, frame->p, frame->size);
if(size<0 && (errno != EAGAIN && errno != EINTR)) {
perror("audio write:");
return;
}
if(size>0) {
frame->p+=size; frame->size-=size;
sleep=0;
}
}
if(frame->size<=0) {
frame->stat=0;
wf=(wf+1) % NUM_FRAMES;
}
}
if(sleep) usleep(1);
}
}
main(int argc, char **argv)
{
int fd;
FILE *filefd;
char *arg=0;
boolean mute = false;
boolean sync = false;
if (argc < 2) return -1;
asprintf(&arg,"mpg123 --stereo -r 48000 --cdr - %s",argv[1]);
if ( (filefd = popen(arg,"r")) < 0) {
perror("Pipe open:");
return -1;
}
fcntl(fileno(filefd),F_SETFL,O_NONBLOCK);
if((fd = open("/dev/ost/audio",O_RDWR|O_NONBLOCK)) < 0){
perror("AUDIO DEVICE: ");
return -1;
}
audioStop(fd);
audioClearBuffer(fd);
audioSelectSource(fd,AUDIO_SOURCE_MEMORY);
audioSetAVSync(fd,false);
audioSetMute(fd,false);
audioPlay(fd);
audioGetStatus(fd);
play_file_audio(filefd,fd);
audioGetStatus(fd);
audioStop(fd);
audioClearBuffer(fd);
audioSelectSource(fd,AUDIO_SOURCE_DEMUX);
audioSetAVSync(fd,true);
audioSetMute(fd,false);
audioPlay(fd);
audioGetStatus(fd);
close(fd);
return 0;
}
--
Stefan Huelswitt
huels@iname.com | http://home.pages.de/~nathan
--
Info:
To unsubscribe send a mail to listar@linuxtv.org with "unsubscribe linux-dvb" as subject.
Home |
Main Index |
Thread Index