Date: Fri, 20 Dec 2019 23:42:14 +0100 From: Hans Petter Selasky <hps@selasky.org> To: Marcel Bonnet <marcelbonnet@gmail.com> Cc: FreeBSD multimedia <freebsd-multimedia@freebsd.org> Subject: Re: [off-topic] Applying gain to an audio sample Message-ID: <7639f4fe-f021-bfca-13a7-f4d529aa3080@selasky.org> In-Reply-To: <CAPe0dB=DF62Nq-h-mne8itZD-U6dTdhAqPrrV8g9OvHGGmooXg@mail.gmail.com> References: <CAPe0dB=BGyeLX3Xue=nNpHqRn8s-4xAO_T4Asmv-DUGk8uu2Jg@mail.gmail.com> <77875a51-0cef-a27f-7d27-9eac8426bb74@selasky.org> <CAPe0dB=DF62Nq-h-mne8itZD-U6dTdhAqPrrV8g9OvHGGmooXg@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On 2019-12-20 23:02, Marcel Bonnet wrote: > Em sex, 20 de dez de 2019 15:46, Hans Petter Selasky <hps@selasky.org> > escreveu: > >> On 2019-12-20 19:43, Marcel Bonnet wrote: >>> - read an audio sample as integer (stereo 16 bit LE) >>> - convert to float >>> - apply a gain, like: sample *= 0.3f >>> - convert to integer again >> >> The attachment is missing. >> > > Sorry, here it is. > > #include <stdio.h> > #include <unistd.h> > #include <fcntl.h> > #include "/usr/include/sys/soundcard.h" > #include <sys/ioctl.h> > #include <sys/time.h> > #include <sys/stat.h> //man 2 chmod > #include <signal.h> #include <stdint.h> > > #define DEBUG 1 > #define log(msg) if (DEBUG) printf("[LOG] %s\n",msg) > #define err(msg) {printf("[ERR] %s\n",msg); exit(1); } > > > const char *device = "/dev/dsp3.1"; //Audio device > char *rawFile = "/tmp/raw-file.wav"; //Raw file to record and playback > int fragmentSize = 256; > int b_continue = 1; Look here: > > > void signalHandler(int sigNum){ > log("Signal captured"); > b_continue = 0; > } > > > void configDevice(int fdDsp){ > int ossCapabilities = 0; > > if(fdDsp == -1) > err("can't open device"); > > if( ioctl(fdDsp, SNDCTL_DSP_GETCAPS, &ossCapabilities) == -1) > err("unsupported: SNDCTL_DSP_GETCAPS"); > > /* > * http://www.opensound.com/pguide/audio2.html > */ > > if(ossCapabilities & DSP_CAP_TRIGGER != DSP_CAP_TRIGGER){ > err("Triggering of recording/playback is not possible with > this OSS device."); > > } > > if(ossCapabilities & DSP_CAP_REALTIME != DSP_CAP_REALTIME){ > err("No DSP_CAP_REALTIME."); > > } > > if(ioctl(fdDsp, SNDCTL_DSP_SETDUPLEX, &ossCapabilities) == -1) > err("can't SNDCTL_DSP_SETDUPLEX"); > > if(ossCapabilities & DSP_CAP_DUPLEX != DSP_CAP_DUPLEX) > err("can't DSP_CAP_DUPLEX"); > > int format = AFMT_S16_LE; //set format > if(ioctl(fdDsp, SNDCTL_DSP_SETFMT, &format ) == -1){ > err("Error setting format."); > > } > > int channels = 1; //mono=0 stereo=1 > if(ioctl(fdDsp, SNDCTL_DSP_STEREO, &channels ) == -1){ > err("Error setting channels." ); > > } > // FREQUENCY RATE > int speed = 44100; > if(ioctl(fdDsp, SNDCTL_DSP_SPEED, &speed ) == -1){ > err("Error setting speed."); > > } > > // FRAGMENT SIZE > if(ioctl(fdDsp, SNDCTL_DSP_SETBLKSIZE, &fragmentSize) == -1){ > //normalmente 2048 bits > err("Cannot SNDCTL_DSP_SETBLKSIZE."); > > } > > > } > > void record(){ > int fdDsp = open(device, O_RDONLY); > configDevice(fdDsp); > //create file for writing > const int fdOutput = open(rawFile, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR); > > if(fdOutput ==-1) > err("can't open file to write"); > log("Recording..."); > > do{ > // Triggers recording > int enableBits = PCM_ENABLE_INPUT; > if(ioctl(fdDsp, SNDCTL_DSP_SETTRIGGER, &enableBits) == -1) > err("Can't record: SNDCTL_DSP_SETTRIGGER"); > This buffer declaration is wrong. > int *buf[fragmentSize]; Use: int16_t buf[fragmentSize / sizeof(int16_t)]; > read(fdDsp, buf, sizeof(buf)); > write(fdOutput, buf, sizeof(buf)); > > } while(b_continue == 1); > > close(fdOutput); > close(fdDsp); > } > > void playback(){ > log("Opening file:"); > log(rawFile); > log("On device:"); > log(device); > > int fdDsp = open(device, O_WRONLY); > configDevice(fdDsp); > > const int fdInput = open(rawFile, O_RDONLY); > > if(fdInput ==-1) > err("can't open file"); > log("Playing..."); > > int eof = 0; > > do{ > // TRIGGERs PLAYBACK > int enableBits = PCM_ENABLE_OUTPUT; > if(ioctl(fdDsp, SNDCTL_DSP_SETTRIGGER, &enableBits) == -1){ > err("Cannot SNDCTL_DSP_SETTRIGGER."); > > } > Ditto: int16_t buf[fragmentSize / sizeof(int16_t)]; > eof = read(fdInput, buf, sizeof(buf)); //bytes read or -1 if EOF > > // audio processing: > for(int i=0;i < fragmentSize;i++){ float sample = buf[i]; sample *= 0.3; buf[i] = sample; > } > > write(fdDsp, buf, fragmentSize); > if(b_continue == 0) break; > } while(eof > 0); > > close(fdInput); > close(fdDsp); > } > > int main(int argc, char *argv[]) > { > > signal(SIGINT, signalHandler); > log("Ctrl^C to stop recording/playback"); > record(); > b_continue = 1; playback(); > log("Stopped."); > return 0; > } > > > > >> Probably better to use the host endian version of AFMT > > > You mean AFMT_S16_NE ? The native endian? Yes. Try my corrections first. --HPS
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?7639f4fe-f021-bfca-13a7-f4d529aa3080>