📄 sound_sun.cc
字号:
#pragma implementation#ifdef SUN// if supported use AUDIO_ENCODING_LINEAR, else AUDIO_ENCODING_ULAW// if uncertain, try linear first and see if you get an error message//#define AUDIO_ENCODING AUDIO_ENCODING_LINEAR#define AUDIO_ENCODING AUDIO_ENCODING_ULAW#define AUDIO_DEV "/dev/audio" #define AUDIOCTL_DEV "/dev/audioctl"extern "C" {#include <multimedia/libaudio.h>#include <multimedia/audio_device.h>#include <multimedia/audio_encode.h> }#include <stdio.h>#include <fcntl.h> #include <unistd.h> #include <stropts.h>#include <errno.h>#include <fcntl.h>#include <string.h>#include <fstream.h>#include "sound_sun.h"#include "others/sndblock.h"#include "sample.h" SunSound::SunSound (int sample_rate, int b) : name_("SunSound"), error_(false), bits(b){ audio_fd = open(AUDIO_DEV, O_RDONLY); audio_pause_record(audio_fd); if (audio_fd < 0) { errmsg_ = "Could not open " AUDIO_DEV; error_ = true; return; }#if AUDIO_ENCODING == AUDIO_ENCODING_LINEAR bytes_per_unit = bits/8;#elif AUDIO_ENCODING == AUDIO_ENCODING_ULAW bytes_per_unit = 1; if (bits == 8) { errmsg_ = "Set SOUND_BITS 16 in .earsrc for ulaw encoding.\n"; error_ = true; return; }#endif int audioctl_fd = open(AUDIOCTL_DEV, O_RDWR); Audio_hdr config; config.sample_rate = sample_rate; config.bytes_per_unit = bytes_per_unit; config.encoding = AUDIO_ENCODING; config.data_size = AUDIO_UNKNOWN_SIZE; int error = audio_set_record_config(audioctl_fd, &config); audio_get_record_config(audioctl_fd, &config); if (AUDIO_ENCODING != config.encoding) { errmsg_ = "Linear format not supported, change encoding to AUDIO_ENCODING_ULAW\n" "in modules/sound_sun.cc. See Readme.sun for details.\n"; error_ = true; return; } else if (config.sample_rate != sample_rate || config.bytes_per_unit != bytes_per_unit) {#if AUDIO_ENCODING == AUDIO_ENCODING_LINEAR errmsg_ = "Could not set audio device to requested settings.\n" "Try SOUND_BITS 8; SOUND_SPEED 8000 in .earsrc.\n";#elif AUDIO_ENCODING == AUDIO_ENCODING_ULAW errmsg_ = "Could not set audio device to requested settings.\n" "Try SOUND_BITS 16; SOUND_SPEED 8000 in .earsrc.\n";#endif error_ = true; return; }}SunSound::~SunSound(){ audio_flush_record(audio_fd); close(audio_fd);} void SunSound::deaf_mic(){ audio_pause_record(audio_fd); } void SunSound::full_mic(){ audio_resume_record(audio_fd);} void SunSound::empty_buffer() const{ audio_flush_record(audio_fd); } void SunSound::save_sample (const class sample& s, const string& f) const{ // not implemented} static unsigned char buffer[400]; // should be big enoughvoid SunSound::fill_block (sndblock& s) const{ int size = s.size_; switch (bytes_per_unit) { case 1: for (int k = 0; k < size;) { k += read(audio_fd, (void *) (buffer + k), (size - k)); } for (int k = size; k--;) {#if AUDIO_ENCODING == AUDIO_ENCODING_LINEAR s.buf_[k] = buffer[k]; #elif AUDIO_ENCODING == AUDIO_ENCODING_ULAW /* convert ulaw to linear using freely redistributable code -- ** per the copyright notice by Sun Microsystems in Readme.sun */#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */#define QUANT_MASK (0xf) /* Quantization field mask. */#define SEG_SHIFT (4) /* Left shift for segment number. */#define SEG_MASK (0x70) /* Segment field mask. */#define BIAS (0x84) /* Bias for linear code. */ unsigned char u_val = ~buffer[k]; int t = ((u_val & QUANT_MASK) << 3) + BIAS; t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; s.buf_[k] = ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS)); #endif } break; case 2: for (int k = 0; k < size;) { k += read(audio_fd, (void *) (s.buf_ + k), 2*(size - k))/2; } } long sum = 0; short last = s.buf_[size-1]; int diff; for (int k = size; k--;) { diff = s.buf_[k] - last; diff = (diff > 0) ? diff : -diff; sum += diff; last = s.buf_[k]; } s.energy_ = sum / size;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -