Mailing List Archive

[PATCH] mono support, take three
Hi John and Isaac,

Here is the latest version of my mono and 8bit support patch. Mono
should work both uncompressed and compressed while 8bit only works
uncompressed. I got rid of the dynamic configuration by changing the
init order as was suggested. It works well for me.

-Jim

Index: libs/libNuppelVideo/NuppelVideoPlayer.cpp
===================================================================
RCS file: /var/lib/cvs/MC/libs/libNuppelVideo/NuppelVideoPlayer.cpp,v
retrieving revision 1.99
diff -u -r1.99 NuppelVideoPlayer.cpp
--- libs/libNuppelVideo/NuppelVideoPlayer.cpp 24 Nov 2002 01:57:46 -0000 1.99
+++ libs/libNuppelVideo/NuppelVideoPlayer.cpp 24 Nov 2002 05:41:32 -0000
@@ -83,7 +83,11 @@
weMadeBuffer = false;

osd = NULL;
+ audio_bits = 16;
+ audio_channels = 2;
audio_samplerate = 44100;
+ audio_bytes_per_sample = audio_channels * audio_bits/8;
+
editmode = false;
advancevideo = resetvideo = advancedecoder = false;

@@ -245,13 +249,13 @@

void NuppelVideoPlayer::InitSound(void)
{
- int bits = 16, stereo = 1, speed = audio_samplerate, caps;
+ int caps;

if (usingextradata)
{
- bits = extradata.audio_bits_per_sample;
- stereo = (extradata.audio_channels == 2);
- speed = extradata.audio_sample_rate;
+ audio_bits = extradata.audio_bits_per_sample;
+ audio_channels = extradata.audio_channels;
+ audio_samplerate = extradata.audio_sample_rate;
}

if (disableaudio)
@@ -268,29 +272,21 @@
return;
}

- if (ioctl(audiofd, SNDCTL_DSP_SAMPLESIZE, &bits) < 0)
- {
- cerr << "problem setting sample size, exiting\n";
+ if (ioctl(audiofd, SNDCTL_DSP_SAMPLESIZE, &audio_bits) < 0 ||
+ ioctl(audiofd, SNDCTL_DSP_CHANNELS, &audio_channels) < 0 ||
+ ioctl(audiofd, SNDCTL_DSP_SPEED, &audio_samplerate) < 0)
+ {
+ cerr << "player: " << audiodevice
+ << ": error setting audio output device to "
+ << audio_samplerate << "kHz/"
+ << audio_bits << "bits/"
+ << audio_channels << "channel\n";
close(audiofd);
audiofd = -1;
return;
}

- if (ioctl(audiofd, SNDCTL_DSP_STEREO, &stereo) < 0)
- {
- cerr << "problem setting to stereo, exiting\n";
- close(audiofd);
- audiofd = -1;
- return;
- }
-
- if (ioctl(audiofd, SNDCTL_DSP_SPEED, &speed) < 0)
- {
- cerr << "problem setting sample rate, exiting\n";
- close(audiofd);
- audiofd = -1;
- return;
- }
+ audio_bytes_per_sample = audio_channels * audio_bits/8;

if (ioctl(audiofd, SNDCTL_DSP_GETCAPS, &caps) >= 0 &&
!(caps & DSP_CAP_REALTIME))
@@ -559,7 +555,12 @@
foundit = 0;
effdsp = audio_samplerate;
if (usingextradata)
+ {
effdsp = extradata.audio_sample_rate;
+ audio_channels = extradata.audio_channels;
+ audio_bits = extradata.audio_bits_per_sample;
+ audio_bytes_per_sample = audio_channels * audio_bits/8;
+ }

while (!foundit)
{
@@ -979,8 +980,8 @@
ioctl(audiofd, SNDCTL_DSP_GETODELAY, &soundcard_buffer); // bytes
totalbuffer = audiolen(false) + soundcard_buffer;

- audiotime = audbuf_timecode - (int)((double)totalbuffer * 25000.0 /
- (double)effdsp);
+ audiotime = audbuf_timecode -
+ (int)(totalbuffer * 100000.0 / (audio_bytes_per_sample * effdsp));

gettimeofday(&audiotime_updated, NULL);

@@ -1096,7 +1097,6 @@
else if (frameheader.comptype=='3')
{
int lameret = 0;
- int len = 0;
short int pcmlbuffer[audio_samplerate];
short int pcmrbuffer[audio_samplerate];
int packetlen = frameheader.packetlength;
@@ -1113,9 +1113,9 @@
int itemp = 0;
int afree = audiofree(false);

- if (lameret * 4 > afree)
+ if (lameret * audio_bytes_per_sample > afree)
{
- lameret = afree / 4;
+ lameret = afree / audio_bytes_per_sample;
cout << "Audio buffer overflow, audio data lost!\n";
}

@@ -1124,10 +1124,9 @@
for (itemp = 0; itemp < lameret; itemp++)
{
saudbuffer[waud / 2] = pcmlbuffer[itemp];
- saudbuffer[waud / 2 + 1] = pcmrbuffer[itemp];
-
- waud += 4;
- len += 4;
+ if(audio_channels == 2)
+ saudbuffer[waud / 2 + 1] = pcmrbuffer[itemp];
+ waud += audio_bytes_per_sample;
if (waud >= AUDBUFSIZE)
waud -= AUDBUFSIZE;
}
@@ -1518,8 +1517,8 @@
/* do audio output */

/* approximate # of audio bytes for each frame. */
- bytesperframe = 4 * (int)((1.0/video_frame_rate) *
- ((double)effdsp/100.0) + 0.5);
+ bytesperframe = audio_bytes_per_sample *
+ (int)(effdsp / 100.0 / video_frame_rate + 0.5);

// wait for the buffer to fill with enough to play
if (bytesperframe >= audiolen(true))
Index: libs/libNuppelVideo/NuppelVideoPlayer.h
===================================================================
RCS file: /var/lib/cvs/MC/libs/libNuppelVideo/NuppelVideoPlayer.h,v
retrieving revision 1.49
diff -u -r1.49 NuppelVideoPlayer.h
--- libs/libNuppelVideo/NuppelVideoPlayer.h 20 Nov 2002 23:37:33 -0000 1.49
+++ libs/libNuppelVideo/NuppelVideoPlayer.h 24 Nov 2002 05:41:33 -0000
@@ -190,6 +190,9 @@
unsigned char *directbuf;
char lastct;
int effdsp; // from the recorded stream
+ int audio_channels; // from the recorded stream
+ int audio_bits; // per channel per sample
+ int audio_bytes_per_sample;
int audio_samplerate; // rate to tell the output device
int filesize;
int startpos;
Index: libs/libNuppelVideo/NuppelVideoRecorder.cpp
===================================================================
RCS file: /var/lib/cvs/MC/libs/libNuppelVideo/NuppelVideoRecorder.cpp,v
retrieving revision 1.63
diff -u -r1.63 NuppelVideoRecorder.cpp
--- libs/libNuppelVideo/NuppelVideoRecorder.cpp 20 Nov 2002 23:37:33 -0000 1.63
+++ libs/libNuppelVideo/NuppelVideoRecorder.cpp 24 Nov 2002 05:41:34 -0000
@@ -71,7 +71,10 @@
keyframedist = KEYFRAMEDIST;

audiobytes = 0;
+ audio_bits = 16;
+ audio_channels = 2;
audio_samplerate = 44100;
+ audio_bytes_per_sample = audio_channels * audio_bits/8;

picture_format = PIX_FMT_YUV420P;

@@ -253,15 +256,25 @@
int videomegs;
int audiomegs = 2;

+ if (AudioInit() != 0)
+ {
+ cerr << "Could not detect audio blocksize\n";
+ }
+
if (compressaudio)
{
gf = lame_init();
lame_set_bWriteVbrTag(gf, 0);
lame_set_quality(gf, mp3quality);
lame_set_compression_ratio(gf, 11);
+ lame_set_mode(gf, audio_channels == 2 ? STEREO : MONO);
+ lame_set_num_channels(gf, audio_channels);
lame_set_out_samplerate(gf, audio_samplerate);
lame_set_in_samplerate(gf, audio_samplerate);
lame_init_params(gf);
+ if(audio_bits != 16) {
+ cerr << "lame support requires 16bit audio\n";
+ }
}

if (codec == "hardware-mjpeg")
@@ -282,11 +295,6 @@

video_buffer_count = (videomegs * 1000 * 1000) / video_buffer_size;

- if (AudioInit() != 0)
- {
- cerr << "Could not detect audio blocksize\n";
- }
-
if (audio_buffer_size != 0)
audio_buffer_count = (audiomegs * 1000 * 1000) / audio_buffer_size;
else
@@ -313,7 +321,7 @@
int NuppelVideoRecorder::AudioInit(void)
{
int afmt, afd;
- int frag, channels, rate, blocksize = 4096;
+ int frag, blocksize = 4096;

if (-1 == (afd = open(audiodevice.ascii(), O_RDONLY)))
{
@@ -334,22 +342,19 @@
return(1);
}

- channels = 2;
- ioctl(afd, SNDCTL_DSP_CHANNELS, &channels);
-
- /* sample rate */
- rate = audio_samplerate;
- if (ioctl(afd, SNDCTL_DSP_SPEED, &rate) < 0)
- {
- cerr << "setting sample rate failed, exiting\n";
+ if (ioctl(afd, SNDCTL_DSP_SAMPLESIZE, &audio_bits) < 0 ||
+ ioctl(afd, SNDCTL_DSP_CHANNELS, &audio_channels) < 0 ||
+ ioctl(afd, SNDCTL_DSP_SPEED, &audio_samplerate) < 0)
+ {
+ cerr << "recorder: " << audiodevice
+ << ": error setting audio input device to "
+ << audio_samplerate << "kHz/"
+ << audio_bits << "bits/"
+ << audio_channels << "channel\n";
return 1;
}

- if (rate != audio_samplerate)
- {
- cerr << "setting sample rate to " << audio_samplerate << " failed\n";
- return 1;
- }
+ audio_bytes_per_sample = audio_channels * audio_bits/8;

if (-1 == ioctl(afd, SNDCTL_DSP_GETBLKSIZE, &blocksize))
{
@@ -1107,7 +1112,7 @@
}

moredata.audio_sample_rate = audio_samplerate;
- moredata.audio_channels = 2;
+ moredata.audio_channels = audio_channels;
moredata.audio_bits_per_sample = 16;

extendeddataOffset = ringBuffer->GetFileWritePosition();
@@ -1238,7 +1243,7 @@
{
int afmt = 0, trigger = 0;
int afd = 0, act = 0, lastread = 0;
- int frag = 0, channels = 0, rate = 0, blocksize = 0;
+ int frag = 0, blocksize = 0;
unsigned char *buffer;
audio_buf_info ispace;
struct timeval anow;
@@ -1265,12 +1270,20 @@
return;
}

- channels = 2;
- ioctl(afd, SNDCTL_DSP_CHANNELS, &channels);
+ if (ioctl(afd, SNDCTL_DSP_SAMPLESIZE, &audio_bits) < 0 ||
+ ioctl(afd, SNDCTL_DSP_CHANNELS, &audio_channels) < 0 ||
+ ioctl(afd, SNDCTL_DSP_SPEED, &audio_samplerate) < 0)
+ {
+ cerr << "recorder: " << audiodevice
+ << ": error setting audio input device to "
+ << audio_samplerate << "kHz/"
+ << audio_bits << "bits/"
+ << audio_channels << "channel\n";
+ close(afd);
+ return;
+ }

- /* sample rate */
- rate = audio_samplerate;
- ioctl(afd, SNDCTL_DSP_SPEED, &rate);
+ audio_bytes_per_sample = audio_channels * audio_bits/8;

if (-1 == ioctl(afd, SNDCTL_DSP_GETBLKSIZE, &blocksize))
{
@@ -1339,8 +1352,8 @@
/* Back up the timecode. The more stuff is in the hw buffer,
the earlier this audio was actually recorded. */
audiobuffer[act]->timecode -=
- (int) ( ( (double)ispace.fragments * (double)ispace.fragsize * 1000.0 ) /
- ( (double)audio_samplerate * 4.0 ) );
+ (int)(ispace.fragments * ispace.fragsize * 1000.0 /
+ (audio_samplerate * audio_bytes_per_sample));

memcpy(audiobuffer[act]->buffer, buffer, audio_buffer_size);

@@ -1718,12 +1731,12 @@
// wrong guess ;-)
// need seconds instead of msec's
//mt = (double)timecode/1000.0;
- mt = (double)timecode;
+ mt = timecode;
if (mt > 0.0)
{
//eff = (abytes/4.0)/mt;
//effectivedsp=(int)(100.0*eff);
- eff = (abytes/mt)*((double)100000.0/(double)4.0);
+ eff = (abytes/mt)*(100000.0 / audio_bytes_per_sample);
effectivedsp=(int)eff;
}
}
@@ -1735,10 +1748,21 @@
int gaplesssize = 0;
int lameret = 0;

- lameret = lame_encode_buffer_interleaved(gf, (short int *)buf,
- audio_buffer_size / 4,
- (unsigned char *)mp3buf,
- mp3buf_size);
+ if(audio_channels == 2)
+ {
+ lameret = lame_encode_buffer_interleaved(gf, (short int *)buf,
+ audio_buffer_size / audio_bytes_per_sample,
+ (unsigned char *)mp3buf,
+ mp3buf_size);
+ }
+ else
+ {
+ lameret = lame_encode_buffer(gf, (short int *)buf, (short int *)buf,
+ audio_buffer_size / audio_bytes_per_sample,
+ (unsigned char *)mp3buf,
+ mp3buf_size);
+ }
+
if (lameret < 0)
{
cerr << "lame error, exiting\n";
Index: libs/libNuppelVideo/NuppelVideoRecorder.h
===================================================================
RCS file: /var/lib/cvs/MC/libs/libNuppelVideo/NuppelVideoRecorder.h,v
retrieving revision 1.25
diff -u -r1.25 NuppelVideoRecorder.h
--- libs/libNuppelVideo/NuppelVideoRecorder.h 18 Nov 2002 01:59:38 -0000 1.25
+++ libs/libNuppelVideo/NuppelVideoRecorder.h 24 Nov 2002 05:41:34 -0000
@@ -126,6 +126,9 @@
int compression;
int compressaudio;
unsigned long long audiobytes;
+ int audio_channels; // channels to request from sounddevice
+ int audio_bits; // per channel per sample
+ int audio_bytes_per_sample;
int audio_samplerate; // rate we request from sounddevice
int effectivedsp; // actual measured rate
Re: [PATCH] mono support, take three [ In reply to ]
On Sunday 24 November 2002 12:53 am, Jim Radford wrote:
> Hi John and Isaac,
>
> Here is the latest version of my mono and 8bit support patch. Mono
> should work both uncompressed and compressed while 8bit only works
> uncompressed. I got rid of the dynamic configuration by changing the
> init order as was suggested. It works well for me.

Thanks Jim -- that looks great. I just applied it to CVS. I really
appreciate you going back and changing things around for me.

I added a 'compressaudio = false' to the cerr clause if 8 bit samples get
tried with lame, so stuff should still work with that.

Isaac