Hi John,
On Mon, Nov 18, 2002 at 11:53:03PM -0500, John Coiner wrote:
> It would be great to parameterize all of the player/recorder code in
> terms of 'channels' and 'bytes_per_sample' etc. The option to use mono
> would be pretty sweet for people with mono tuners, especially if they
> don't have the world's fastest CPU.
Ok here it is. I actually have sound now for the first time. And
it's in sync!
> ( By the way -- if you're going to work on the player -- take a minute
> to see if you can figure out how the audio buffer's read pointer could
> "lap" the write pointer. This should never happen, though Isaac seems to
> have observed just this. We were stymied, the code looked pretty solid,
> to me anyway...)
Will do, now that I have a better grasp on the code.
-Jim
Index: libs/libNuppelVideo/NuppelVideoPlayer.cpp
===================================================================
RCS file: /var/lib/cvs/MC/libs/libNuppelVideo/NuppelVideoPlayer.cpp,v
retrieving revision 1.96
diff -u -r1.96 NuppelVideoPlayer.cpp
--- libs/libNuppelVideo/NuppelVideoPlayer.cpp 18 Nov 2002 01:59:38 -0000 1.96
+++ libs/libNuppelVideo/NuppelVideoPlayer.cpp 19 Nov 2002 10:37:59 -0000
@@ -41,6 +41,7 @@
#define wsEnter 0x8d + 256
#define wsReturn 0x0d + 256
+int audio_ioctl_int(int fd, int arg, int *value, const char *decscription);
NuppelVideoPlayer::NuppelVideoPlayer(void)
{
@@ -75,7 +76,9 @@
weMadeBuffer = false;
osd = NULL;
+ audio_channels = 2;
audio_samplerate = 44100;
+ audio_bits_per_sample = 16;
editmode = false;
advancevideo = resetvideo = advancedecoder = false;
@@ -171,13 +174,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_per_sample = extradata.audio_bits_per_sample;
+ audio_channels = extradata.audio_channels;
+ audio_samplerate = extradata.audio_sample_rate;
}
if (disableaudio)
@@ -194,25 +197,10 @@
return;
}
- if (ioctl(audiofd, SNDCTL_DSP_SAMPLESIZE, &bits) < 0)
- {
- cerr << "problem setting sample size, exiting\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)
+ if(audio_ioctl_int(audiofd, SNDCTL_DSP_CHANNELS, &audio_channels, "audio output channels") < 0 ||
+ audio_ioctl_int(audiofd, SNDCTL_DSP_SPEED, &audio_samplerate, "audio output samplerate") < 0 ||
+ audio_ioctl_int(audiofd, SNDCTL_DSP_SAMPLESIZE, &audio_bits_per_sample, "audio output bits per sample") < 0)
{
- cerr << "problem setting sample rate, exiting\n";
close(audiofd);
audiofd = -1;
return;
@@ -480,7 +468,11 @@
foundit = 0;
effdsp = audio_samplerate;
if (usingextradata)
+ {
effdsp = extradata.audio_sample_rate;
+ audio_channels = extradata.audio_channels;
+ audio_bits_per_sample = extradata.audio_bits_per_sample;
+ }
while (!foundit)
{
@@ -856,8 +848,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_bits_per_sample/8 * audio_channels * effdsp));
gettimeofday(&audiotime_updated, NULL);
@@ -993,17 +985,29 @@
do
{
- lameret = lame_decode(strm, packetlen, pcmlbuffer,
- pcmrbuffer);
+ mp3data_struct header;
+ lameret = lame_decode_headers(strm, packetlen, pcmlbuffer,
+ pcmrbuffer, &header);
if (lameret > 0)
{
int itemp = 0;
int afree = audiofree(false);
- if (lameret * 4 > afree)
+ if(header.header_parsed && header.stereo != audio_channels &&
+ audio_ioctl_int(audiofd, SNDCTL_DSP_CHANNELS, &(audio_channels=header.stereo),
+ "audio mp3 output channels") < 0 ||
+ header.header_parsed && header.samplerate != audio_samplerate &&
+ audio_ioctl_int(audiofd, SNDCTL_DSP_SPEED, &(audio_samplerate=header.samplerate),
+ "audio mp3 output samplerate") < 0)
+ {
+ close(audiofd);
+ audiofd = -1;
+ }
+
+ if (lameret * audio_channels * audio_bits_per_sample/8 > afree)
{
- lameret = afree / 4;
+ lameret = afree / audio_channels / (audio_bits_per_sample/8);
cout << "Audio buffer overflow, audio data lost!\n";
}
@@ -1011,11 +1015,17 @@
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] = pcmlbuffer[itemp];
+ saudbuffer[waud / 2 + 1] = pcmrbuffer[itemp];
+ }
+ else
+ {
+ saudbuffer[waud] = pcmlbuffer[itemp];
+ }
+ waud += audio_channels * audio_bits_per_sample/8;
+ len += audio_channels * audio_bits_per_sample/8;
if (waud >= AUDBUFSIZE)
waud -= AUDBUFSIZE;
}
@@ -1388,8 +1398,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_channels * audio_bits_per_sample/8) *
+ (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.48
diff -u -r1.48 NuppelVideoPlayer.h
--- libs/libNuppelVideo/NuppelVideoPlayer.h 15 Nov 2002 00:12:07 -0000 1.48
+++ libs/libNuppelVideo/NuppelVideoPlayer.h 19 Nov 2002 10:37:59 -0000
@@ -183,6 +183,8 @@
unsigned char *buf2;
char lastct;
int effdsp; // from the recorded stream
+ int audio_channels; // from the recorded stream
+ int audio_bits_per_sample; // per channel
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.62
diff -u -r1.62 NuppelVideoRecorder.cpp
--- libs/libNuppelVideo/NuppelVideoRecorder.cpp 18 Nov 2002 01:59:38 -0000 1.62
+++ libs/libNuppelVideo/NuppelVideoRecorder.cpp 19 Nov 2002 10:38:00 -0000
@@ -24,6 +24,21 @@
pthread_mutex_t avcodeclock = PTHREAD_MUTEX_INITIALIZER;
+int audio_ioctl_int(int fd, int arg, int *value, const char *decscription)
+{
+ int ret, orig = *value;
+
+ cout << "setting " << decscription << " to " << *value << endl;
+
+ if ((ret=ioctl(fd, arg, value)) < 0)
+ cerr << "problem setting " << decscription << ", exiting\n";
+ else
+ if(orig != *value)
+ cout << decscription << " forced to use " << *value
+ << " instead of " << orig << endl;
+ return ret;
+}
+
NuppelVideoRecorder::NuppelVideoRecorder(void)
{
sfilename = "output.nuv";
@@ -71,6 +86,8 @@
keyframedist = KEYFRAMEDIST;
audiobytes = 0;
+ audio_channels = 2;
+ audio_bits_per_sample = 16;
audio_samplerate = 44100;
picture_format = PIX_FMT_YUV420P;
@@ -259,6 +276,8 @@
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);
@@ -313,5 +332,5 @@
int NuppelVideoRecorder::AudioInit(void)
{
int afmt, afd;
- int frag, channels, rate, blocksize = 4096;
+ int frag, blocksize = 4096;
@@ -331,30 +351,18 @@
if (afmt != AFMT_S16_LE)
{
cerr << "Can't get 16 bit DSP, exiting\n";
- 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";
return 1;
}
- if (rate != audio_samplerate)
- {
- cerr << "setting sample rate to " << audio_samplerate << " failed\n";
- return 1;
- }
+ if(audio_ioctl_int(afd, SNDCTL_DSP_CHANNELS, &audio_channels, "audio input channels") < 0 ||
+ audio_ioctl_int(afd, SNDCTL_DSP_SPEED, &audio_samplerate, "audio input samplerate") < 0 ||
+ audio_ioctl_int(afd, SNDCTL_DSP_SAMPLESIZE, &audio_bits_per_sample, "audio input bits per sample") < 0)
+ return 1;
if (-1 == ioctl(afd, SNDCTL_DSP_GETBLKSIZE, &blocksize))
{
cerr << "Can't get DSP blocksize, exiting\n";
- return(1);
+ return 1;
}
blocksize *= 4;
@@ -1107,8 +1115,8 @@
}
moredata.audio_sample_rate = audio_samplerate;
- moredata.audio_channels = 2;
- moredata.audio_bits_per_sample = 16;
+ moredata.audio_channels = audio_channels;
+ moredata.audio_bits_per_sample = audio_bits_per_sample;
extendeddataOffset = ringBuffer->GetFileWritePosition();
@@ -1238,8 +1246,8 @@
{
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 +1274,13 @@
return;
}
- channels = 2;
- ioctl(afd, SNDCTL_DSP_CHANNELS, &channels);
-
- /* sample rate */
- rate = audio_samplerate;
- ioctl(afd, SNDCTL_DSP_SPEED, &rate);
+ if(audio_ioctl_int(afd, SNDCTL_DSP_CHANNELS, &audio_channels, "audio input channels") < 0 ||
+ audio_ioctl_int(afd, SNDCTL_DSP_SPEED, &audio_samplerate, "audio input samplerate") < 0 ||
+ audio_ioctl_int(afd, SNDCTL_DSP_SAMPLESIZE, &audio_bits_per_sample, "audio input bits per sample") < 0)
+ {
+ close(afd);
+ return;
+ }
if (-1 == ioctl(afd, SNDCTL_DSP_GETBLKSIZE, &blocksize))
{
@@ -1339,8 +1349,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_bits_per_sample/8 * audio_channels));
memcpy(audiobuffer[act]->buffer, buffer, audio_buffer_size);
@@ -1728,12 +1738,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_bits_per_sample/8) / audio_channels);
effectivedsp=(int)eff;
}
}
@@ -1745,10 +1755,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_channels / (audio_bits_per_sample/8),
+ (unsigned char *)mp3buf,
+ mp3buf_size);
+ }
+ else
+ {
+ lameret = lame_encode_buffer(gf, (short int *)buf, (short int *)buf,
+ audio_buffer_size / audio_channels / (audio_bits_per_sample/8),
+ (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 19 Nov 2002 10:38:00 -0000
@@ -126,6 +126,8 @@
int compression;
int compressaudio;
unsigned long long audiobytes;
+ int audio_channels; // channels to request from sounddevice
+ int audio_bits_per_sample; // per channel
int audio_samplerate; // rate we request from sounddevice
int effectivedsp; // actual measured rate
On Mon, Nov 18, 2002 at 11:53:03PM -0500, John Coiner wrote:
> It would be great to parameterize all of the player/recorder code in
> terms of 'channels' and 'bytes_per_sample' etc. The option to use mono
> would be pretty sweet for people with mono tuners, especially if they
> don't have the world's fastest CPU.
Ok here it is. I actually have sound now for the first time. And
it's in sync!
> ( By the way -- if you're going to work on the player -- take a minute
> to see if you can figure out how the audio buffer's read pointer could
> "lap" the write pointer. This should never happen, though Isaac seems to
> have observed just this. We were stymied, the code looked pretty solid,
> to me anyway...)
Will do, now that I have a better grasp on the code.
-Jim
Index: libs/libNuppelVideo/NuppelVideoPlayer.cpp
===================================================================
RCS file: /var/lib/cvs/MC/libs/libNuppelVideo/NuppelVideoPlayer.cpp,v
retrieving revision 1.96
diff -u -r1.96 NuppelVideoPlayer.cpp
--- libs/libNuppelVideo/NuppelVideoPlayer.cpp 18 Nov 2002 01:59:38 -0000 1.96
+++ libs/libNuppelVideo/NuppelVideoPlayer.cpp 19 Nov 2002 10:37:59 -0000
@@ -41,6 +41,7 @@
#define wsEnter 0x8d + 256
#define wsReturn 0x0d + 256
+int audio_ioctl_int(int fd, int arg, int *value, const char *decscription);
NuppelVideoPlayer::NuppelVideoPlayer(void)
{
@@ -75,7 +76,9 @@
weMadeBuffer = false;
osd = NULL;
+ audio_channels = 2;
audio_samplerate = 44100;
+ audio_bits_per_sample = 16;
editmode = false;
advancevideo = resetvideo = advancedecoder = false;
@@ -171,13 +174,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_per_sample = extradata.audio_bits_per_sample;
+ audio_channels = extradata.audio_channels;
+ audio_samplerate = extradata.audio_sample_rate;
}
if (disableaudio)
@@ -194,25 +197,10 @@
return;
}
- if (ioctl(audiofd, SNDCTL_DSP_SAMPLESIZE, &bits) < 0)
- {
- cerr << "problem setting sample size, exiting\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)
+ if(audio_ioctl_int(audiofd, SNDCTL_DSP_CHANNELS, &audio_channels, "audio output channels") < 0 ||
+ audio_ioctl_int(audiofd, SNDCTL_DSP_SPEED, &audio_samplerate, "audio output samplerate") < 0 ||
+ audio_ioctl_int(audiofd, SNDCTL_DSP_SAMPLESIZE, &audio_bits_per_sample, "audio output bits per sample") < 0)
{
- cerr << "problem setting sample rate, exiting\n";
close(audiofd);
audiofd = -1;
return;
@@ -480,7 +468,11 @@
foundit = 0;
effdsp = audio_samplerate;
if (usingextradata)
+ {
effdsp = extradata.audio_sample_rate;
+ audio_channels = extradata.audio_channels;
+ audio_bits_per_sample = extradata.audio_bits_per_sample;
+ }
while (!foundit)
{
@@ -856,8 +848,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_bits_per_sample/8 * audio_channels * effdsp));
gettimeofday(&audiotime_updated, NULL);
@@ -993,17 +985,29 @@
do
{
- lameret = lame_decode(strm, packetlen, pcmlbuffer,
- pcmrbuffer);
+ mp3data_struct header;
+ lameret = lame_decode_headers(strm, packetlen, pcmlbuffer,
+ pcmrbuffer, &header);
if (lameret > 0)
{
int itemp = 0;
int afree = audiofree(false);
- if (lameret * 4 > afree)
+ if(header.header_parsed && header.stereo != audio_channels &&
+ audio_ioctl_int(audiofd, SNDCTL_DSP_CHANNELS, &(audio_channels=header.stereo),
+ "audio mp3 output channels") < 0 ||
+ header.header_parsed && header.samplerate != audio_samplerate &&
+ audio_ioctl_int(audiofd, SNDCTL_DSP_SPEED, &(audio_samplerate=header.samplerate),
+ "audio mp3 output samplerate") < 0)
+ {
+ close(audiofd);
+ audiofd = -1;
+ }
+
+ if (lameret * audio_channels * audio_bits_per_sample/8 > afree)
{
- lameret = afree / 4;
+ lameret = afree / audio_channels / (audio_bits_per_sample/8);
cout << "Audio buffer overflow, audio data lost!\n";
}
@@ -1011,11 +1015,17 @@
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] = pcmlbuffer[itemp];
+ saudbuffer[waud / 2 + 1] = pcmrbuffer[itemp];
+ }
+ else
+ {
+ saudbuffer[waud] = pcmlbuffer[itemp];
+ }
+ waud += audio_channels * audio_bits_per_sample/8;
+ len += audio_channels * audio_bits_per_sample/8;
if (waud >= AUDBUFSIZE)
waud -= AUDBUFSIZE;
}
@@ -1388,8 +1398,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_channels * audio_bits_per_sample/8) *
+ (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.48
diff -u -r1.48 NuppelVideoPlayer.h
--- libs/libNuppelVideo/NuppelVideoPlayer.h 15 Nov 2002 00:12:07 -0000 1.48
+++ libs/libNuppelVideo/NuppelVideoPlayer.h 19 Nov 2002 10:37:59 -0000
@@ -183,6 +183,8 @@
unsigned char *buf2;
char lastct;
int effdsp; // from the recorded stream
+ int audio_channels; // from the recorded stream
+ int audio_bits_per_sample; // per channel
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.62
diff -u -r1.62 NuppelVideoRecorder.cpp
--- libs/libNuppelVideo/NuppelVideoRecorder.cpp 18 Nov 2002 01:59:38 -0000 1.62
+++ libs/libNuppelVideo/NuppelVideoRecorder.cpp 19 Nov 2002 10:38:00 -0000
@@ -24,6 +24,21 @@
pthread_mutex_t avcodeclock = PTHREAD_MUTEX_INITIALIZER;
+int audio_ioctl_int(int fd, int arg, int *value, const char *decscription)
+{
+ int ret, orig = *value;
+
+ cout << "setting " << decscription << " to " << *value << endl;
+
+ if ((ret=ioctl(fd, arg, value)) < 0)
+ cerr << "problem setting " << decscription << ", exiting\n";
+ else
+ if(orig != *value)
+ cout << decscription << " forced to use " << *value
+ << " instead of " << orig << endl;
+ return ret;
+}
+
NuppelVideoRecorder::NuppelVideoRecorder(void)
{
sfilename = "output.nuv";
@@ -71,6 +86,8 @@
keyframedist = KEYFRAMEDIST;
audiobytes = 0;
+ audio_channels = 2;
+ audio_bits_per_sample = 16;
audio_samplerate = 44100;
picture_format = PIX_FMT_YUV420P;
@@ -259,6 +276,8 @@
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);
@@ -313,5 +332,5 @@
int NuppelVideoRecorder::AudioInit(void)
{
int afmt, afd;
- int frag, channels, rate, blocksize = 4096;
+ int frag, blocksize = 4096;
@@ -331,30 +351,18 @@
if (afmt != AFMT_S16_LE)
{
cerr << "Can't get 16 bit DSP, exiting\n";
- 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";
return 1;
}
- if (rate != audio_samplerate)
- {
- cerr << "setting sample rate to " << audio_samplerate << " failed\n";
- return 1;
- }
+ if(audio_ioctl_int(afd, SNDCTL_DSP_CHANNELS, &audio_channels, "audio input channels") < 0 ||
+ audio_ioctl_int(afd, SNDCTL_DSP_SPEED, &audio_samplerate, "audio input samplerate") < 0 ||
+ audio_ioctl_int(afd, SNDCTL_DSP_SAMPLESIZE, &audio_bits_per_sample, "audio input bits per sample") < 0)
+ return 1;
if (-1 == ioctl(afd, SNDCTL_DSP_GETBLKSIZE, &blocksize))
{
cerr << "Can't get DSP blocksize, exiting\n";
- return(1);
+ return 1;
}
blocksize *= 4;
@@ -1107,8 +1115,8 @@
}
moredata.audio_sample_rate = audio_samplerate;
- moredata.audio_channels = 2;
- moredata.audio_bits_per_sample = 16;
+ moredata.audio_channels = audio_channels;
+ moredata.audio_bits_per_sample = audio_bits_per_sample;
extendeddataOffset = ringBuffer->GetFileWritePosition();
@@ -1238,8 +1246,8 @@
{
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 +1274,13 @@
return;
}
- channels = 2;
- ioctl(afd, SNDCTL_DSP_CHANNELS, &channels);
-
- /* sample rate */
- rate = audio_samplerate;
- ioctl(afd, SNDCTL_DSP_SPEED, &rate);
+ if(audio_ioctl_int(afd, SNDCTL_DSP_CHANNELS, &audio_channels, "audio input channels") < 0 ||
+ audio_ioctl_int(afd, SNDCTL_DSP_SPEED, &audio_samplerate, "audio input samplerate") < 0 ||
+ audio_ioctl_int(afd, SNDCTL_DSP_SAMPLESIZE, &audio_bits_per_sample, "audio input bits per sample") < 0)
+ {
+ close(afd);
+ return;
+ }
if (-1 == ioctl(afd, SNDCTL_DSP_GETBLKSIZE, &blocksize))
{
@@ -1339,8 +1349,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_bits_per_sample/8 * audio_channels));
memcpy(audiobuffer[act]->buffer, buffer, audio_buffer_size);
@@ -1728,12 +1738,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_bits_per_sample/8) / audio_channels);
effectivedsp=(int)eff;
}
}
@@ -1745,10 +1755,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_channels / (audio_bits_per_sample/8),
+ (unsigned char *)mp3buf,
+ mp3buf_size);
+ }
+ else
+ {
+ lameret = lame_encode_buffer(gf, (short int *)buf, (short int *)buf,
+ audio_buffer_size / audio_channels / (audio_bits_per_sample/8),
+ (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 19 Nov 2002 10:38:00 -0000
@@ -126,6 +126,8 @@
int compression;
int compressaudio;
unsigned long long audiobytes;
+ int audio_channels; // channels to request from sounddevice
+ int audio_bits_per_sample; // per channel
int audio_samplerate; // rate we request from sounddevice
int effectivedsp; // actual measured rate