[oss-devel] New to OSS
Rizwan Khan
rizwaan at gmail.com
Thu Jun 28 20:23:48 EEST 2007
Dear Sir:
Thanks for your kind response.
I have attached the audiolevel.c code which i copied from OSS site. I
need your favor to use this and to add following things, since i am
very new to OSS and can not find any clue how to do the following
work:
-How i can test this program i.e. audiolevel.c
>>You can call SNDCTL_DSP_GETISPACE to find out how many bytes of recorded
>>data is currently available. However doing this doesn't necessarily make
>>the program better.
Can you please give any single example this, i tried to add this in
audiolevel.c but did not get success. Can you please add this in the
attached audiolevel.c
>>> And how its map from device name back to device?
>>You can call SNDCTL_AUDIOINFO (on the file descriptor returned by
>>open()) and use the device name returned in the name field.
Can you please add this SNDCTL_AUDIOINFO in attached audiolevel.c code,
Also i wanted to use FlushData function, can you please give me idea
of doing this in OSS.
I will be very thankfull if you can do so and give me clue, how to do this work,
Best Regards,
On 6/28/07, Hannu Savolainen <hannu at opensound.com> wrote:
> Rizwan Khan kirjoitti:
> > Hello
> >
> > I am new to OSS and needs your expert advise.
> > I want to prototype a linux based sound recorder using OSS which has
> > this type of interface methods.
> >
> > SRecorder...
> >
> > bool Open(... device, samplerate, channels...);
> > void Start();
> > bool WaitForDataAndRead(LThread& Interface, int16_t* Buffer);
> > void Stop();
> > samplecount_t FlushData(int16_t* Buffer);
> > void Close();
> > I want that audio should be 16 bit PCM.
> >
> > At the moment, I am following this exacmple program and started with:
> > http://manuals.opensound.com/developer/audiolevel.c.html
> >
> > in this program i am concerned about:
> > (a) What is the blocking mode (does read block)
> >
> Yes. Reads will block until the requested amount of recorded data is
> available.
> > - if blocking how do we determine the number of samples ready
> >
> You can call SNDCTL_DSP_GETISPACE to find out how many bytes of recorded
> data is currently available. However doing this doesn't necessarily make
> the program better.
> > (b) Is close missing there?
> >
> Close is missing because this program will never exit. It will keep
> running until somebody kills it.
> > (c) Did this work?
> >
> It did work.
> > Also - how what devices are possible as the input to this program.
> You can use ossinfo -a -v and look for the devices that report "Mode:
> IN" or "Mode: IN/OUT". Programs can use the SNDCTL_AUDIOINFO call to
> find out which devices support recording.
> > And how its map from device name back to device?
> >
> You can call SNDCTL_AUDIOINFO (on the file descriptor returned by
> open()) and use the device name returned in the name field.
>
> Best regards,
>
> Hannu
> _______________________________________________
> oss-devel mailing list
> oss-devel at mailman.opensound.com
> http://mailman.opensound.com/mailman/listinfo/oss-devel
>
--
Muhammad R!zwän Khän
-------------- next part --------------
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/soundcard.h>
int fd_in;
int sample_rate = 48000;
//The open_audio_device opens the audio device and initializes it for the required mode.
//The same routine is used in the other simple sample programs too.
static int
open_audio_device (char *name, int mode)
{
int tmp, fd;
if ((fd = open (name, mode, 0)) == -1)
{
perror (name);
exit (-1);
}
//Setup the device. Note that it's important to set the sample format, number of channels and
//sample rate exactly in this order. Some devices depend on the order.
Set the sample format
tmp = AFMT_S16_NE; /* Native 16 bits */
if (ioctl (fd, SNDCTL_DSP_SETFMT, &tmp) == -1)
{
perror ("SNDCTL_DSP_SETFMT");
exit (-1);
}
if (tmp != AFMT_S16_NE)
{
fprintf (stderr,
"The device doesn't support the 16 bit sample format.\n");
exit (-1);
}
//Set the number of channels (mono)
tmp = 1;
if (ioctl (fd, SNDCTL_DSP_CHANNELS, &tmp) == -1)
{
perror ("SNDCTL_DSP_CHANNELS");
exit (-1);
}
if (tmp != 1)
{
fprintf (stderr, "The device doesn't support mono mode.\n");
exit (-1);
}
//Set the sample rate
sample_rate = 48000;
if (ioctl (fd, SNDCTL_DSP_SPEED, &sample_rate) == -1)
{
perror ("SNDCTL_DSP_SPEED");
exit (-1);
}
//No need for error checking because we will automatically adjust the signal based on
//the actual sample rate. However most application must check the value of sample_rate
//and compare it to the requested rate. Small differences between the rates (10% or less)
//are normal and the applications should usually tolerate them. However larger differences
//may cause annoying pitch problems (Mickey Mouse).
return fd;
}
void
process_input (void)
{
short buffer[1024];
int l, i, level;
//First read a block of audio samples with proper error checking.
if ((l = read (fd_in, buffer, sizeof (buffer))) == -1)
{
perror ("Audio read");
exit (-1); /* Or return an error code */
}
//We are using 16 bit samples so the number of bytes returned by read must be
//converted to the number of samples (2 bytes per a 16 bit sample).
//Some care must be taken if this program is converted from 1 channels
//(mono) to 2 channels (stereo) or more. Handling more than 1 channels is bit more
//complicated because the channels are interleaved. This will be demonstrated in some other programs.
l = l / 2;
//After this point this routine will perform the peak volume computations.
//The l variable contains the number of samples in the buffer.
//The remaining lines can be removed and replaced with the required application code.
level = 0;
for (i = 0; i < l; i++)
{
//Take the next sample (i) and compute it's absolute value.
//Check if it was larger than the previous peak value.
int v = buffer[i];
if (v < 0)
v = -v; /* abs */
if (v > level)
level = v;
}
//Finally print the simple LED bar. The maximum value for a 16 bit sample
//is 32*1024-1. Convert this to 32 bars. This program uses linear scale for simplicity.
//Real world audio programs should probably use logarithmic scale (dB).
level = (level + 1) / 1024;
for (i = 0; i < level; i++)
printf ("*");
for (i = level; i < 32; i++)
printf (".");
printf ("\r");
fflush (stdout);
}
int
main (int argc, char *argv[])
{
//Use /dev/dsp as the default device because the system administrator may select
// the device using the ossctl program or some other methods
char *name_out = "/dev/dsp";
//It's recommended to provide some method for selecting some other device than the default.
//We use command line argument but in some cases an environment variable or some
//configuration file setting may be better.
if (argc > 1)
name_out = argv[1];
//It's mandatory to use O_RDONLY in programs that do only recording. Other modes may
//cause increased resource (memory) usage in the driver. It may also prevent other
//applications from using the same device for playback at the same time.
fd_in = open_audio_device (name_out, O_RDONLY);
while (1)
process_input ();
exit (0);
}
More information about the oss-devel
mailing list