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