mirror of
https://github.com/n5ac/mmtty.git
synced 2025-12-06 04:12:03 +01:00
1352 lines
32 KiB
C++
1352 lines
32 KiB
C++
|
|
//Copyright+LGPL
|
|||
|
|
|
|||
|
|
//-----------------------------------------------------------------------------------------------------------------------------------------------
|
|||
|
|
// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba, Dave Bernstein
|
|||
|
|
//-----------------------------------------------------------------------------------------------------------------------------------------------
|
|||
|
|
// This file is part of MMTTY.
|
|||
|
|
|
|||
|
|
// MMTTY is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
|
|||
|
|
// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|||
|
|
|
|||
|
|
// MMTTY is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|||
|
|
|
|||
|
|
// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see
|
|||
|
|
// <http://www.gnu.org/licenses/>.
|
|||
|
|
//-----------------------------------------------------------------------------------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
#include <vcl.h>
|
|||
|
|
#pragma hdrstop
|
|||
|
|
|
|||
|
|
#include <io.h>
|
|||
|
|
|
|||
|
|
#include "Sound.h"
|
|||
|
|
#include "Main.h"
|
|||
|
|
|
|||
|
|
WAVEINCAPS InCaps;
|
|||
|
|
WAVEOUTCAPS OutCaps;
|
|||
|
|
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
// <20><><EFBFBD><EFBFBD>: VCL <20>I<EFBFBD>u<EFBFBD>W<EFBFBD>F<EFBFBD>N<EFBFBD>g<EFBFBD>̃<EFBFBD><CC83>\<5C>b<EFBFBD>h<EFBFBD>ƃv<C683><76><EFBFBD>p<EFBFBD>e<EFBFBD>B<EFBFBD><42><EFBFBD>g<EFBFBD>p<EFBFBD><70><EFBFBD><EFBFBD><EFBFBD>ɂ<EFBFBD>, Synchronize
|
|||
|
|
// <20><><EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\<5C>b<EFBFBD>h<EFBFBD>Ăяo<D18F><6F><EFBFBD>łȂ<C582><C882><EFBFBD><EFBFBD>Ȃ<CE82><C882>܂<EFBFBD><DC82><EFBFBD><EFBFBD>B<EFBFBD><42><EFBFBD>ɗ<EFBFBD><C997><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><DC82>B
|
|||
|
|
//
|
|||
|
|
// Synchronize(UpdateCaption);
|
|||
|
|
//
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, UpdateCaption <20>͎<EFBFBD><CD8E>̂悤<CC82>ɋL<C98B>q<EFBFBD>ł<EFBFBD><C582>܂<EFBFBD><DC82>B
|
|||
|
|
//
|
|||
|
|
// void __fastcall TSound::UpdateCaption()
|
|||
|
|
// {
|
|||
|
|
// Form1->Caption = "<22>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD><68><EFBFBD>珑<EFBFBD><E78F91><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><DC82><EFBFBD>";
|
|||
|
|
// }
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
__fastcall TSound::TSound(bool CreateSuspended)
|
|||
|
|
: TThread(CreateSuspended)
|
|||
|
|
{
|
|||
|
|
::VirtualLock(this, sizeof(TSound));
|
|||
|
|
|
|||
|
|
if( SampType == 2 ){
|
|||
|
|
m_FFTWINDOW = (3000 * FFT_SIZE / SampFreq);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_FFTWINDOW = (4000 * FFT_SIZE / SampFreq);
|
|||
|
|
}
|
|||
|
|
m_BuffSize = SampSize;
|
|||
|
|
m_Stop = TRUE;
|
|||
|
|
memset(ZBPF, 0, sizeof(ZBPF));
|
|||
|
|
memset(HBPF, 0, sizeof(HBPF));
|
|||
|
|
|
|||
|
|
m_ReqFifoSize = 0;
|
|||
|
|
m_IDDevice = WAVE_MAPPER;
|
|||
|
|
m_IDOutDevice = WAVE_MAPPER; //AA6YQ 1.6.6
|
|||
|
|
m_playmode = 0;
|
|||
|
|
m_susp = 0;
|
|||
|
|
m_suspack = 0;
|
|||
|
|
m_bpf = 0;
|
|||
|
|
m_lmsbpf = 0;
|
|||
|
|
m_bpffw = 100.0;
|
|||
|
|
m_bpftap = 56;
|
|||
|
|
m_bpfafc = 1;
|
|||
|
|
CalcBPF();
|
|||
|
|
|
|||
|
|
InitWFX();
|
|||
|
|
m_Test = 0;
|
|||
|
|
m_Noise = 0;
|
|||
|
|
m_FFTSW = 1;
|
|||
|
|
m_FFTFW = 0;
|
|||
|
|
m_Tx = m_ReqTx = 0;
|
|||
|
|
FSKMOD.SetDem(&FSKDEM);
|
|||
|
|
|
|||
|
|
m_FFTMax = 128;
|
|||
|
|
m_FFTSumMax = 128*2;
|
|||
|
|
|
|||
|
|
m_WaterMax = 128;
|
|||
|
|
m_WaterSumMax = 128*8;
|
|||
|
|
m_WaterMin = 0;
|
|||
|
|
|
|||
|
|
m_ReqSpeedTest = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
__fastcall TSound::~TSound()
|
|||
|
|
{
|
|||
|
|
::VirtualUnlock(this, sizeof(TSound));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void __fastcall TSound::InitWFX(void)
|
|||
|
|
{
|
|||
|
|
m_WFX.wFormatTag = WAVE_FORMAT_PCM;
|
|||
|
|
m_WFX.nChannels = WORD(sys.m_SoundStereo ? 2 : 1);
|
|||
|
|
m_WFX.wBitsPerSample = 16;
|
|||
|
|
m_WFX.nSamplesPerSec = int(SampBase);
|
|||
|
|
m_WFX.nBlockAlign = WORD(m_WFX.nChannels *(m_WFX.wBitsPerSample/8));
|
|||
|
|
m_WFX.nAvgBytesPerSec = m_WFX.nBlockAlign * m_WFX.nSamplesPerSec;
|
|||
|
|
m_WFX.cbSize = 0;
|
|||
|
|
Wave.m_SoundStereo = sys.m_SoundStereo;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void __fastcall TSound::CalcBPF(void)
|
|||
|
|
{
|
|||
|
|
MakeFilter(HBPF, m_bpftap, ffBPF, SampFreq, FSKDEM.GetMarkFreq() - m_bpffw, FSKDEM.GetSpaceFreq() + m_bpffw, 60, 1.0);
|
|||
|
|
m_lms.SetWindow(FSKDEM.GetMarkFreq(), FSKDEM.GetSpaceFreq());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void __fastcall TSound::CalcBPF(double fl, double fh, double fw)
|
|||
|
|
{
|
|||
|
|
MakeFilter(HBPF, m_bpftap, ffBPF, SampFreq, fl - fw, fh + fw, 60, 1.0);
|
|||
|
|
m_lms.SetWindow(fl, fh);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void __fastcall TSound::Stop(void)
|
|||
|
|
{
|
|||
|
|
if( m_Stop == FALSE ){
|
|||
|
|
Priority = tpNormal;
|
|||
|
|
Terminate();
|
|||
|
|
WaitFor();
|
|||
|
|
Wave.InClose();
|
|||
|
|
Wave.OutAbort();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void __fastcall TSound::ReqStop(void)
|
|||
|
|
{
|
|||
|
|
if( m_Stop == FALSE ){
|
|||
|
|
Priority = tpNormal;
|
|||
|
|
Terminate();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void __fastcall TSound::WaitStop(void)
|
|||
|
|
{
|
|||
|
|
WaitFor();
|
|||
|
|
Wave.InClose();
|
|||
|
|
Wave.OutAbort();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void __fastcall TSound::InitSound(void)
|
|||
|
|
{
|
|||
|
|
Suspend();
|
|||
|
|
FSKMOD.SetSampFreq(SampFreq + sys.m_TxOffset);
|
|||
|
|
InitWFX();
|
|||
|
|
m_ReqFifoSize = TRUE;
|
|||
|
|
Resume();
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall TSound::ErrorMsg(void)
|
|||
|
|
{
|
|||
|
|
if( m_IDDevice == -2 ){
|
|||
|
|
InfoMB("Sound I/O failed in the MMW (%s)", sys.m_SoundMMW.c_str());
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
ErrorMB((sys.m_WinFontCharset != SHIFTJIS_CHARSET)?"Can't open Sound card (%d)":"<EFBFBD>T<EFBFBD>E<EFBFBD><EFBFBD><EFBFBD>h<EFBFBD>J<EFBFBD>[<5B>h<EFBFBD><68><EFBFBD>I<EFBFBD>[<5B>v<EFBFBD><76><EFBFBD>ł<EFBFBD><C582>܂<EFBFBD><DC82><EFBFBD>.", m_IDDevice);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
BOOL __fastcall TSound::ReInitSound(void)
|
|||
|
|
{
|
|||
|
|
if( Terminated == TRUE ) return FALSE;
|
|||
|
|
Wave.OutAbort();
|
|||
|
|
Wave.InClose();
|
|||
|
|
InitWFX();
|
|||
|
|
if( m_Err >= 3 ){
|
|||
|
|
m_Err = 5;
|
|||
|
|
::Sleep(100);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_Err++;
|
|||
|
|
}
|
|||
|
|
if( m_Tx || (m_playmode == 1) ){
|
|||
|
|
if( (sys.m_TxPort != txTXDOnly) || (m_playmode == 1) ){
|
|||
|
|
if( Wave.OutOpen(&m_WFX, m_IDOutDevice, m_BuffSize) ) return TRUE; //AA6YQ 1.66
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if( Wave.InOpen(&m_WFX, m_IDDevice, m_BuffSize) ) return TRUE;
|
|||
|
|
}
|
|||
|
|
return FALSE;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
int __fastcall TSound::UpdateFifoSize(void)
|
|||
|
|
{
|
|||
|
|
int r = 2;
|
|||
|
|
if( !m_ReqFifoSize ) return 1;
|
|||
|
|
|
|||
|
|
int fi = Wave.IsInOpen();
|
|||
|
|
int fo = Wave.IsOutOpen();
|
|||
|
|
if( fi ) Wave.InClose();
|
|||
|
|
if( fo ) Wave.OutAbort();
|
|||
|
|
Wave.m_InFifoSize = sys.m_SoundFifoRX;
|
|||
|
|
Wave.m_OutFifoSize = sys.m_SoundFifoTX;
|
|||
|
|
m_IDDevice = sys.m_SoundDevice;
|
|||
|
|
m_IDOutDevice = sys.m_SoundOutDevice; //AA6YQ 1.66
|
|||
|
|
Wave.UpdateDevice(m_IDDevice);
|
|||
|
|
if( fi ){
|
|||
|
|
if( !Wave.InOpen(&m_WFX, m_IDDevice, m_BuffSize) ) r = FALSE;
|
|||
|
|
}
|
|||
|
|
if( fo ){
|
|||
|
|
if( !Wave.OutOpen(&m_WFX, m_IDOutDevice, m_BuffSize) ) r = FALSE; //AA6YQ 1.66
|
|||
|
|
}
|
|||
|
|
TaskPriority();
|
|||
|
|
m_ReqFifoSize = 0;
|
|||
|
|
return r;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall TSound::TaskPriority(void)
|
|||
|
|
{
|
|||
|
|
switch(sys.m_SoundPriority){
|
|||
|
|
case 0:
|
|||
|
|
if( Priority != tpNormal ){
|
|||
|
|
Priority = tpNormal; //<2F>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD>͒ʏ<CD92><CA8F>̗D<CC97><44><EFBFBD>x<EFBFBD>ł<EFBFBD><C582><EFBFBD>
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 1:
|
|||
|
|
if( Priority != tpHigher ){
|
|||
|
|
Priority = tpHigher; //<2F>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD>̗D<CC97><44><EFBFBD>x<EFBFBD>͒ʏ<CD92><CA8F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1 <20>|<7C>C<EFBFBD><43><EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD>
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 2:
|
|||
|
|
if( Priority != tpHighest ){
|
|||
|
|
Priority = tpHighest; //<2F>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD>̗D<CC97><44><EFBFBD>x<EFBFBD>͒ʏ<CD92><CA8F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2 <20>|<7C>C<EFBFBD><43><EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD>
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
if( Priority != tpTimeCritical ){
|
|||
|
|
Priority = tpTimeCritical; //<2F>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD>͂<EFBFBD><CD82><EFBFBD><EFBFBD>Ƃ<EFBFBD><C682><EFBFBD><EFBFBD><EFBFBD><EFBFBD>D<EFBFBD><44><EFBFBD>x<EFBFBD><78><EFBFBD>擾<EFBFBD><E693BE><EFBFBD><EFBFBD>
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall TSound::Execute()
|
|||
|
|
{
|
|||
|
|
static double Buff[8192];
|
|||
|
|
double *lp;
|
|||
|
|
int i;
|
|||
|
|
int Len;
|
|||
|
|
|
|||
|
|
m_Stop = FALSE;
|
|||
|
|
memset(Buff, 0, sizeof(Buff));
|
|||
|
|
TaskPriority();
|
|||
|
|
::Sleep(200); // 200ms
|
|||
|
|
Wave.m_InFifoSize = sys.m_SoundFifoRX;
|
|||
|
|
Wave.m_OutFifoSize = sys.m_SoundFifoTX;
|
|||
|
|
m_IDDevice = sys.m_SoundDevice;
|
|||
|
|
m_IDOutDevice = sys.m_SoundOutDevice; //AA6YQ 1.66
|
|||
|
|
Wave.UpdateDevice(m_IDDevice);
|
|||
|
|
_init:;
|
|||
|
|
Wave.InClose();
|
|||
|
|
if( Wave.InOpen(&m_WFX, m_IDDevice, m_BuffSize) != TRUE ){
|
|||
|
|
int timeout = Wave.GetTimeout() / 200;
|
|||
|
|
for( int i = 0; i < timeout; i++ ){
|
|||
|
|
::Sleep(200);
|
|||
|
|
if( Terminated == TRUE ) goto _ex;
|
|||
|
|
if( UpdateFifoSize() == 2 ) goto _init;
|
|||
|
|
if( Wave.InOpen(&m_WFX, m_IDDevice, m_BuffSize) == TRUE ) break;
|
|||
|
|
}
|
|||
|
|
if( Wave.IsInOpen() != TRUE ){
|
|||
|
|
if( timeout ) ErrorMsg();
|
|||
|
|
if( Terminated == TRUE ) goto _ex;
|
|||
|
|
int Count = 3000/50;
|
|||
|
|
while(1){ // <20>[<5B><><EFBFBD><EFBFBD><EFBFBD>s
|
|||
|
|
if( Terminated == TRUE ) goto _ex;
|
|||
|
|
::Sleep(50);
|
|||
|
|
Wave.PumpMessages();
|
|||
|
|
if( (m_Tx != m_ReqTx) || m_ReqFifoSize || !Count ){
|
|||
|
|
Count = 3000/50;
|
|||
|
|
if( UpdateFifoSize() == 2 ) goto _init;
|
|||
|
|
m_Tx = m_ReqTx;
|
|||
|
|
if( Wave.InOpen(&m_WFX, m_IDDevice, m_BuffSize) == TRUE ) break;
|
|||
|
|
}
|
|||
|
|
Count--;
|
|||
|
|
}
|
|||
|
|
m_Tx = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
m_Tx = 0;
|
|||
|
|
Wave.OutAbort();
|
|||
|
|
Len = m_BuffSize;
|
|||
|
|
while(1){
|
|||
|
|
if( Terminated == TRUE ) break;
|
|||
|
|
if( Wave.IsInOpen() ){
|
|||
|
|
if( Wave.InRead(Buff, m_BuffSize) == FALSE ){
|
|||
|
|
if( !ReInitSound() ) goto _init;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( m_playmode && (!m_Tx || (m_playmode != 1))) WaveFile.ReadWrite(Buff, m_BuffSize);
|
|||
|
|
if( Terminated == TRUE ) break;
|
|||
|
|
if( m_Test && !m_Tx ){
|
|||
|
|
for( i = 0, lp = Buff; i < Len; i++, lp++ ){
|
|||
|
|
if( m_Test ) *lp += FSKMOD.Do(1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( m_bpf || m_lmsbpf ){
|
|||
|
|
for( i = 0, lp = Buff; i < Len; i++, lp++ ){
|
|||
|
|
if( m_bpf ){
|
|||
|
|
*lp = DoFIR(HBPF, ZBPF, *lp, m_bpftap);
|
|||
|
|
}
|
|||
|
|
if( m_lmsbpf ){
|
|||
|
|
*lp = m_lms.Do(*lp);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( m_FFTSW ) fftIN.CollectFFT(Buff, Len);
|
|||
|
|
if( !m_Tx || sys.m_echo ){
|
|||
|
|
for( i = 0, lp = Buff; i < Len; i++, lp++ ){
|
|||
|
|
FSKDEM.Do(*lp);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
_skip1:;
|
|||
|
|
if( m_Tx ){
|
|||
|
|
if( (sys.m_echo == 2) && Wave.IsInBufCritical() && Wave.IsInOpen() ) goto _skip2;
|
|||
|
|
for( i = 0, lp = Buff; i < Len; i++, lp++ ){
|
|||
|
|
*lp = FSKMOD.Do(sys.m_echo);
|
|||
|
|
if( (m_ReqTx != m_Tx) && !m_ReqTx && (!FSKMOD.GetMode()) ){
|
|||
|
|
for( ; i < Len; i++, lp++ ) *lp = 0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( (sys.m_TxPort == txTXDOnly) && !Wave.IsInOpen() && (m_ReqTx == m_Tx)){
|
|||
|
|
if( FSKCount1 <= FSKCount2 ){
|
|||
|
|
::Sleep(Len * 1000 / SampFreq);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
::Sleep(1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( Wave.IsOutOpen() == TRUE ){
|
|||
|
|
if( Wave.OutWrite(Buff, Len) != TRUE ){
|
|||
|
|
ReInitSound();
|
|||
|
|
if( Wave.OutWrite(Buff, Len) != TRUE ){
|
|||
|
|
if( !ReInitSound() ) goto _init;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if( (sys.m_echo == 2) && m_Tx && Wave.IsInBufNull() && !Wave.IsOutBufFull() ) goto _skip1;
|
|||
|
|
// if( (sys.m_echo == 2) && m_Tx && !Wave.IsInBufCritical() && !Wave.IsOutBufFull() ) goto _skip1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
_skip2:;
|
|||
|
|
if( m_Tx != m_ReqTx ){
|
|||
|
|
if( !m_ReqTx ){ // To RX
|
|||
|
|
Wave.OutAbort();
|
|||
|
|
fftIN.ClearBuf();
|
|||
|
|
if( !Wave.IsInOpen() ){
|
|||
|
|
Wave.m_InFifoSize = sys.m_SoundFifoRX;
|
|||
|
|
Wave.InOpen(&m_WFX, m_IDDevice, m_BuffSize);
|
|||
|
|
FSKDEM.m_OverFlow = 0;
|
|||
|
|
FSKDEM.ClearMode();
|
|||
|
|
}
|
|||
|
|
m_Tx = m_ReqTx = 0;
|
|||
|
|
Wave.SetPTT(m_Tx);
|
|||
|
|
TaskPriority();
|
|||
|
|
}
|
|||
|
|
else { // To TX
|
|||
|
|
if( sys.m_echo != 2 ){
|
|||
|
|
Wave.InClose();
|
|||
|
|
fftIN.ClearBuf();
|
|||
|
|
}
|
|||
|
|
FSKMOD.InitPhase();
|
|||
|
|
FSKMOD.SetCount(m_BuffSize * 3);
|
|||
|
|
if((sys.m_TxPort != txTXDOnly) && (m_playmode != 1) ){
|
|||
|
|
Wave.m_OutFifoSize = sys.m_SoundFifoTX;
|
|||
|
|
m_IDOutDevice = sys.m_SoundOutDevice; //AA6YQ 1.66
|
|||
|
|
Wave.OutOpen(&m_WFX, m_IDOutDevice, m_BuffSize); //AA6YQ 1.66
|
|||
|
|
if( sys.m_echo == 2 ){
|
|||
|
|
memset(Buff, 0, sizeof(Buff));
|
|||
|
|
for( i = 0; (i < 4) && !Wave.IsOutBufFull(); i++ ){
|
|||
|
|
if( Wave.OutWrite(Buff, Len) != TRUE ) break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( sys.m_echo != 2 ){
|
|||
|
|
FSKDEM.m_OverFlow = 0;
|
|||
|
|
FSKDEM.ClearMode();
|
|||
|
|
}
|
|||
|
|
m_Tx = m_ReqTx;
|
|||
|
|
Wave.SetPTT(m_Tx);
|
|||
|
|
TaskPriority();
|
|||
|
|
}
|
|||
|
|
if( m_playmode == 1 ) m_playmode = 0;
|
|||
|
|
}
|
|||
|
|
if( m_ReqFifoSize ){
|
|||
|
|
if( !UpdateFifoSize() ) goto _init;
|
|||
|
|
}
|
|||
|
|
if( (!m_Tx) && (WaveFile.m_mode != m_playmode) ){
|
|||
|
|
if( WaveFile.m_mode == 1 ){
|
|||
|
|
Wave.InClose();
|
|||
|
|
Wave.m_OutFifoSize = sys.m_SoundFifoTX;
|
|||
|
|
m_IDOutDevice = sys.m_SoundOutDevice; //AA6YQ 1.66
|
|||
|
|
Wave.OutOpen(&m_WFX, m_IDOutDevice, m_BuffSize); //AA6YQ 1.66
|
|||
|
|
FSKDEM.m_OverFlow = 0;
|
|||
|
|
}
|
|||
|
|
else if( m_playmode == 1 ){
|
|||
|
|
Wave.OutClose();
|
|||
|
|
Wave.m_InFifoSize = sys.m_SoundFifoRX;
|
|||
|
|
Wave.InOpen(&m_WFX, m_IDDevice, m_BuffSize);
|
|||
|
|
FSKDEM.m_OverFlow = 0;
|
|||
|
|
}
|
|||
|
|
m_playmode = WaveFile.m_mode;
|
|||
|
|
}
|
|||
|
|
if( m_susp ){
|
|||
|
|
JobSuspend();
|
|||
|
|
}
|
|||
|
|
if( m_ReqSpeedTest ){
|
|||
|
|
JobSpeedTest();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
_ex:;
|
|||
|
|
Wave.InClose();
|
|||
|
|
Wave.OutAbort();
|
|||
|
|
Wave.UpdateDevice(-1);
|
|||
|
|
m_Stop = TRUE;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall TSound::JobSuspend(void)
|
|||
|
|
{
|
|||
|
|
Wave.InClose();
|
|||
|
|
Wave.OutAbort();
|
|||
|
|
m_suspack = 1;
|
|||
|
|
Priority = tpNormal;
|
|||
|
|
while(1){
|
|||
|
|
if( Terminated == TRUE ){
|
|||
|
|
m_Stop = TRUE;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if( m_Tx != m_ReqTx ){
|
|||
|
|
m_Tx = m_ReqTx;
|
|||
|
|
}
|
|||
|
|
Sleep(100);
|
|||
|
|
Wave.PumpMessages();
|
|||
|
|
if( !m_susp ){
|
|||
|
|
for( int i = 0; i < 5; i++ ){
|
|||
|
|
if( Wave.InOpen(&m_WFX, m_IDDevice, m_BuffSize) == TRUE ) break;
|
|||
|
|
::Sleep(100);
|
|||
|
|
Wave.PumpMessages();
|
|||
|
|
}
|
|||
|
|
if( Wave.IsInOpen() ){
|
|||
|
|
m_suspack = 1;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_susp = 1;
|
|||
|
|
m_suspack = 1;
|
|||
|
|
ErrorMsg();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
TaskPriority();
|
|||
|
|
m_Tx = 0;
|
|||
|
|
m_playmode = 0;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
void __fastcall TSound::JobSpeedTest()
|
|||
|
|
{
|
|||
|
|
DWORD tc = ::GetTickCount();
|
|||
|
|
// RTTYMOD.InitTXBuf();
|
|||
|
|
// RTTYDEM.Stop();
|
|||
|
|
for( int i = 0; i < 1000000; i++ ){
|
|||
|
|
FSKMOD.Do(0);
|
|||
|
|
FSKDEM.Do(0);
|
|||
|
|
}
|
|||
|
|
m_SpeedValue = ::GetTickCount() - tc;
|
|||
|
|
m_ReqSpeedTest = 0;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
// <20>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD><68><EFBFBD>ŃR<C583>[<5B><><EFBFBD><EFBFBD><EFBFBD>Ă͂<C482><CD82><EFBFBD><EFBFBD>Ȃ<EFBFBD>
|
|||
|
|
#define AFC_PEAKDOWN 128
|
|||
|
|
int __fastcall TSound::DoAFC(void)
|
|||
|
|
{
|
|||
|
|
if( !sys.m_AFC ) return 0;
|
|||
|
|
if( sys.m_echo != 2 ){
|
|||
|
|
if( m_Tx ) return 0; // <20><><EFBFBD>M<EFBFBD><4D><EFBFBD>͎<EFBFBD><CD8E>s<EFBFBD><73><EFBFBD>Ȃ<EFBFBD>
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
double mfq = FSKDEM.GetMarkFreq();
|
|||
|
|
double sfq = FSKDEM.GetSpaceFreq();
|
|||
|
|
double sft = sfq - mfq;
|
|||
|
|
double sk = sft * 0.5;
|
|||
|
|
|
|||
|
|
int nb = (sft < 50.0) ? 1 : 0;
|
|||
|
|
int xm = mfq * (FFT_SIZE / SampFreq);
|
|||
|
|
int xs = sfq * (FFT_SIZE / SampFreq);
|
|||
|
|
int xc = int((xs - xm) * sys.m_AFCSweep);
|
|||
|
|
int xe = int(xc * 1.2);
|
|||
|
|
if( nb ) xe = 80 * (FFT_SIZE / SampFreq);
|
|||
|
|
int n = 0;
|
|||
|
|
int avg = 0;
|
|||
|
|
|
|||
|
|
int x, xx;
|
|||
|
|
int d;
|
|||
|
|
int max1H = -MAXINT;
|
|||
|
|
int m1H = 0;
|
|||
|
|
for( x = 0; x < xc; x++ ){ // Mark Peak +
|
|||
|
|
xx = xm + x;
|
|||
|
|
if( (xx >= 0) && (xx < m_FFTWINDOW) ){
|
|||
|
|
d = fftIN.m_fft[xx];
|
|||
|
|
if( max1H < d ){
|
|||
|
|
max1H = d;
|
|||
|
|
m1H = xx;
|
|||
|
|
}
|
|||
|
|
else if( (d + AFC_PEAKDOWN) < max1H ){
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
int max1L = -MAXINT;
|
|||
|
|
int m1L = 0;
|
|||
|
|
for( x = 0; x < xe; x++ ){ // Mark Peak -
|
|||
|
|
xx = xm - x;
|
|||
|
|
if( (xx >= 0) && (xx < m_FFTWINDOW) ){
|
|||
|
|
d = fftIN.m_fft[xx];
|
|||
|
|
avg += d;
|
|||
|
|
n++;
|
|||
|
|
if( max1L < d ){
|
|||
|
|
max1L = d;
|
|||
|
|
m1L = xx;
|
|||
|
|
}
|
|||
|
|
else if( (d + AFC_PEAKDOWN) < max1L ){
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int max2H = -MAXINT;
|
|||
|
|
int m2H = 0;
|
|||
|
|
for( x = 0; x < xe; x++ ){ // Space Peak +
|
|||
|
|
xx = xs + x;
|
|||
|
|
if( (xx >= 0) && (xx < m_FFTWINDOW) ){
|
|||
|
|
d = fftIN.m_fft[xx];
|
|||
|
|
avg += d;
|
|||
|
|
n++;
|
|||
|
|
if( max2H < d ){
|
|||
|
|
max2H = d;
|
|||
|
|
m2H = xx;
|
|||
|
|
}
|
|||
|
|
else if( (d + AFC_PEAKDOWN) < max2H ){
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int max2L = -MAXINT;
|
|||
|
|
int m2L = 0;
|
|||
|
|
for( x = 0; x < xc; x++ ){ // Space Peak -
|
|||
|
|
xx = xs - x;
|
|||
|
|
if( (xx >= 0) && (xx < m_FFTWINDOW) ){
|
|||
|
|
d = fftIN.m_fft[xx];
|
|||
|
|
if( max2L < d ){
|
|||
|
|
max2L = d;
|
|||
|
|
m2L = xx;
|
|||
|
|
}
|
|||
|
|
else if( (d + AFC_PEAKDOWN) < max2L ){
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( n ) avg /= n;
|
|||
|
|
|
|||
|
|
// m1l - m1h m2l - m2h
|
|||
|
|
#if 0
|
|||
|
|
FILE *fp = fopen("f:\\test.txt", "at");
|
|||
|
|
fprintf(fp, "%5u %5u %5u %5u\n", m1L, m1H, m2L, m2H);
|
|||
|
|
fclose(fp);
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
if( nb ){
|
|||
|
|
if( max1L < max1H ){ max1L = max1H; m1L = m1H; }
|
|||
|
|
if( max1L < max2L ){ max1L = max2L; m1L = m2L; }
|
|||
|
|
if( max1L < max2H ){ max1L = max2H; m1L = m2H; }
|
|||
|
|
max2L = max1L;
|
|||
|
|
m2L = m1L;
|
|||
|
|
}
|
|||
|
|
else if( m1H == m2L ){
|
|||
|
|
if( max2H > max1L ){
|
|||
|
|
max1L = max1H;
|
|||
|
|
m1L = m1H;
|
|||
|
|
max2L = max2H;
|
|||
|
|
m2L = m2H;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if( max1H > max1L ){
|
|||
|
|
m1L = m1H;
|
|||
|
|
max1L = max1H;
|
|||
|
|
}
|
|||
|
|
if( max2H > max2L ){
|
|||
|
|
m2L = m2H;
|
|||
|
|
max2L = max2H;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( !nb ){
|
|||
|
|
switch(sys.m_FFTGain){
|
|||
|
|
case 0:
|
|||
|
|
if( ((max1L - avg) < sys.m_AFCSQ) || ((max2L - avg) < sys.m_AFCSQ) ) return 0;
|
|||
|
|
break;
|
|||
|
|
case 1:
|
|||
|
|
if( ((max1L - avg) < sys.m_AFCSQ*1.2) || ((max2L - avg) < sys.m_AFCSQ*1.2) ) return 0;
|
|||
|
|
break;
|
|||
|
|
case 2:
|
|||
|
|
if( ((max1L - avg) < sys.m_AFCSQ*1.5) || ((max2L - avg) < sys.m_AFCSQ*1.5) ) return 0;
|
|||
|
|
break;
|
|||
|
|
case 3:
|
|||
|
|
if( ((max1L - avg) < sys.m_AFCSQ*1.8) || ((max2L - avg) < sys.m_AFCSQ*1.8) ) return 0;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
if( ((max1L - avg) < sys.m_AFCSQ*0.5) || ((max2L - avg) < sys.m_AFCSQ*0.5) ) return 0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if( (max1L - avg) < sys.m_AFCSQ*0.5 ) return 0;
|
|||
|
|
}
|
|||
|
|
int ns = m2L - m1L; // <20><><EFBFBD>o<EFBFBD><6F><EFBFBD><EFBFBD><EFBFBD>V<EFBFBD>t<EFBFBD>g<EFBFBD><67>
|
|||
|
|
if( !nb ){
|
|||
|
|
if( ns < int(140.0 * (FFT_SIZE / SampFreq)) ) return 0;
|
|||
|
|
}
|
|||
|
|
if( ns > int(1500.0 * (FFT_SIZE / SampFreq)) ) return 0;
|
|||
|
|
|
|||
|
|
int os = (sft * (FFT_SIZE / SampFreq)); // <20><><EFBFBD>݂̃V<CC83>t<EFBFBD>g<EFBFBD><67>
|
|||
|
|
double nmfq = m1L * (SampFreq / FFT_SIZE);
|
|||
|
|
double nsfq = m2L * (SampFreq / FFT_SIZE);
|
|||
|
|
int ds = ABS(ns-os); // <20>V<EFBFBD>t<EFBFBD>g<EFBFBD><67><EFBFBD>̍<EFBFBD>
|
|||
|
|
switch(sys.m_FixShift){
|
|||
|
|
case 0: // Free
|
|||
|
|
if( nb ) goto _fixed;
|
|||
|
|
if( ((ds <= (os * 1.2)) || nb) && ((nsfq - nmfq) >= 15.0) ){
|
|||
|
|
if( fabs(nmfq - mfq) >= 2.0 ){
|
|||
|
|
mfq += (nmfq - mfq)/sys.m_AFCTime;
|
|||
|
|
}
|
|||
|
|
if( fabs(nsfq - sfq) >= 2.0 ){
|
|||
|
|
sfq += (nsfq - sfq)/sys.m_AFCTime;
|
|||
|
|
}
|
|||
|
|
mfq = double(int(mfq+0.5));
|
|||
|
|
sfq = double(int(sfq+0.5));
|
|||
|
|
if( mfq < MARKL ) mfq = MARKL;
|
|||
|
|
if( sfq > SPACEH ) sfq = SPACEH;
|
|||
|
|
Suspend();
|
|||
|
|
FSKDEM.AFCMarkFreq(mfq);
|
|||
|
|
FSKDEM.AFCSpaceFreq(sfq);
|
|||
|
|
if( m_bpfafc && (FSKDEM.GetAFCMarkFreq() == mfq) && (FSKDEM.GetAFCSpaceFreq() == sfq) ){
|
|||
|
|
CalcBPF();
|
|||
|
|
}
|
|||
|
|
Resume();
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 1: // Fixed Shift
|
|||
|
|
_fixed:;
|
|||
|
|
if( nb ){
|
|||
|
|
double fq = (nmfq + nsfq) / 2;
|
|||
|
|
nmfq = fq - sft/2;
|
|||
|
|
nsfq = fq + sft/2;
|
|||
|
|
}
|
|||
|
|
if( ((ds <= (os * 0.25)) || nb) && ((nsfq - nmfq) >= 15.0) ){
|
|||
|
|
double cfq = (nmfq + nsfq)/2.0;
|
|||
|
|
nmfq = cfq - sk;
|
|||
|
|
if( fabs(nmfq - mfq) >= 2.0 ){
|
|||
|
|
if( nb && (fabs(nmfq - mfq) < 10.0) ){
|
|||
|
|
mfq += (nmfq - mfq)/(sys.m_AFCTime * 4.0);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
mfq += (nmfq - mfq)/sys.m_AFCTime;
|
|||
|
|
}
|
|||
|
|
mfq = double(int(mfq+0.5));
|
|||
|
|
if( mfq < MARKL ) mfq = MARKL;
|
|||
|
|
if( (mfq + sft) > SPACEH ) mfq = SPACEH - sft;
|
|||
|
|
sfq = mfq + sft;
|
|||
|
|
Suspend();
|
|||
|
|
FSKDEM.AFCMarkFreq(mfq);
|
|||
|
|
FSKDEM.AFCSpaceFreq(sfq);
|
|||
|
|
if( m_bpfafc && (FSKDEM.GetAFCMarkFreq() == mfq) && (FSKDEM.GetAFCSpaceFreq() == sfq) ){
|
|||
|
|
CalcBPF();
|
|||
|
|
}
|
|||
|
|
Resume();
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 2: // HAM
|
|||
|
|
if( nb ) goto _fixed;
|
|||
|
|
if( (ns >= 140.0*FFT_SIZE/SampFreq) && (ns <= 260.0*FFT_SIZE/SampFreq) ){
|
|||
|
|
sft = nsfq - nmfq;
|
|||
|
|
if( sft > 230.0 ){
|
|||
|
|
sft = 240.0;
|
|||
|
|
}
|
|||
|
|
else if( sft > 210.0 ){
|
|||
|
|
sft = 220.0;
|
|||
|
|
}
|
|||
|
|
else if( sft > 185 ){
|
|||
|
|
sft = 200.0;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
sft = 170.0;
|
|||
|
|
}
|
|||
|
|
nsfq = nmfq + sft;
|
|||
|
|
if( fabs(nmfq - mfq) >= 2.0 ){
|
|||
|
|
mfq += (nmfq - mfq)/sys.m_AFCTime;
|
|||
|
|
}
|
|||
|
|
if( fabs(nsfq - sfq) >= 2.0 ){
|
|||
|
|
sfq += (nsfq - sfq)/sys.m_AFCTime;
|
|||
|
|
}
|
|||
|
|
mfq = double(int(mfq+0.5));
|
|||
|
|
sfq = double(int(sfq+0.5));
|
|||
|
|
if( mfq < MARKL ) mfq = MARKL;
|
|||
|
|
if( sfq > SPACEH ) sfq = SPACEH;
|
|||
|
|
Suspend();
|
|||
|
|
FSKDEM.AFCMarkFreq(mfq);
|
|||
|
|
FSKDEM.AFCSpaceFreq(sfq);
|
|||
|
|
if( m_bpfafc && (FSKDEM.GetAFCMarkFreq() == mfq) && (FSKDEM.GetAFCSpaceFreq() == sfq) ){
|
|||
|
|
CalcBPF();
|
|||
|
|
}
|
|||
|
|
Resume();
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 3: // FSK
|
|||
|
|
if( (ns >= 140.0*FFT_SIZE/SampFreq) && (ns <= 260.0*FFT_SIZE/SampFreq) ){
|
|||
|
|
sft = nsfq - nmfq;
|
|||
|
|
if( sft > 230.0 ){
|
|||
|
|
sft = 240.0;
|
|||
|
|
}
|
|||
|
|
else if( sft > 210.0 ){
|
|||
|
|
sft = 220.0;
|
|||
|
|
}
|
|||
|
|
else if( sft > 185 ){
|
|||
|
|
sft = 200.0;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
sft = 170.0;
|
|||
|
|
}
|
|||
|
|
nsfq = nmfq + sft;
|
|||
|
|
if( fabs(nmfq - mfq) >= 2.0 ){
|
|||
|
|
nmfq = mfq + (nmfq - mfq)/sys.m_AFCTime;
|
|||
|
|
}
|
|||
|
|
if( fabs(nsfq - sfq) >= 2.0 ){
|
|||
|
|
nsfq = sfq + (nsfq - sfq)/sys.m_AFCTime;
|
|||
|
|
}
|
|||
|
|
sft = nsfq - nmfq;
|
|||
|
|
if( sft < 175 ) sft = 170;
|
|||
|
|
if( sft > 195 ) sft = 200;
|
|||
|
|
sft = double(int((sft*0.5)+0.5));
|
|||
|
|
nmfq = ((sfq + mfq)*0.5) - sft;
|
|||
|
|
nsfq = ((sfq + mfq)*0.5) + sft;
|
|||
|
|
mfq = double(int(nmfq+0.5));
|
|||
|
|
sfq = double(int(nsfq+0.5));
|
|||
|
|
if( mfq < MARKL ) mfq = MARKL;
|
|||
|
|
if( sfq > SPACEH ) sfq = SPACEH;
|
|||
|
|
Suspend();
|
|||
|
|
FSKDEM.AFCMarkFreq(mfq);
|
|||
|
|
FSKDEM.AFCSpaceFreq(sfq);
|
|||
|
|
if( m_bpfafc && (FSKDEM.GetAFCMarkFreq() == mfq) && (FSKDEM.GetAFCSpaceFreq() == sfq) ){
|
|||
|
|
CalcBPF();
|
|||
|
|
}
|
|||
|
|
Resume();
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
double __fastcall TSound::GetScopeRange(double &low, double center, double shift)
|
|||
|
|
{
|
|||
|
|
double FM;
|
|||
|
|
|
|||
|
|
switch(m_FFTFW ){
|
|||
|
|
case 0: // Auto
|
|||
|
|
if( shift >= 800 ){
|
|||
|
|
FM = 3000 * FFT_SIZE / SampFreq;
|
|||
|
|
low = center - 1500;
|
|||
|
|
}
|
|||
|
|
else if( shift >= 400 ){
|
|||
|
|
FM = 2000 * FFT_SIZE / SampFreq;
|
|||
|
|
low = center - 1000;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
FM = 1000 * FFT_SIZE / SampFreq;
|
|||
|
|
low = center - 500;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case 1: // 500
|
|||
|
|
FM = 500 * FFT_SIZE / SampFreq;
|
|||
|
|
low = center - 250;
|
|||
|
|
break;
|
|||
|
|
case 2: // 1000
|
|||
|
|
FM = 1000 * FFT_SIZE / SampFreq;
|
|||
|
|
low = center - 500;
|
|||
|
|
break;
|
|||
|
|
case 3: // 1500
|
|||
|
|
FM = 1500 * FFT_SIZE / SampFreq;
|
|||
|
|
low = center - 750;
|
|||
|
|
break;
|
|||
|
|
case 4: // 2000
|
|||
|
|
FM = 2000 * FFT_SIZE / SampFreq;
|
|||
|
|
low = center - 1000;
|
|||
|
|
break;
|
|||
|
|
default: // 3000
|
|||
|
|
FM = 3000 * FFT_SIZE / SampFreq;
|
|||
|
|
low = center - 1500;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
return FM;
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
// <20>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD><68><EFBFBD>ŃR<C583>[<5B><><EFBFBD><EFBFBD><EFBFBD>Ă͂<C482><CD82><EFBFBD><EFBFBD>Ȃ<EFBFBD>
|
|||
|
|
int __fastcall TSound::DrawFFT(Graphics::TBitmap *pBitmap, int sw, int XRD)
|
|||
|
|
{
|
|||
|
|
if( m_FFTSW ){
|
|||
|
|
if( fftIN.m_CollectFFT ){
|
|||
|
|
switch(sys.m_FFTGain){
|
|||
|
|
case 0:
|
|||
|
|
fftIN.CalcFFT(m_FFTWINDOW, 30.0, sys.m_FFTResp);
|
|||
|
|
break;
|
|||
|
|
case 1:
|
|||
|
|
fftIN.CalcFFT(m_FFTWINDOW, 34.0, sys.m_FFTResp);
|
|||
|
|
break;
|
|||
|
|
case 2:
|
|||
|
|
fftIN.CalcFFT(m_FFTWINDOW, 42.0, sys.m_FFTResp);
|
|||
|
|
break;
|
|||
|
|
case 3:
|
|||
|
|
fftIN.CalcFFT(m_FFTWINDOW, 54.0, sys.m_FFTResp);
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
fftIN.CalcFFT(m_FFTWINDOW, (sys.m_echo != 2 && m_Tx) ? 0.02 : 0.1, sys.m_FFTResp);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
fftIN.TrigFFT();
|
|||
|
|
}
|
|||
|
|
else if( !sw ){
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( Remote & REMSHOWOFF ) return 2;
|
|||
|
|
|
|||
|
|
TCanvas *tp = pBitmap->Canvas;
|
|||
|
|
TRect rc;
|
|||
|
|
int XL = 0;
|
|||
|
|
int XR = pBitmap->Width - 1;
|
|||
|
|
int YT = 0;
|
|||
|
|
int YB = pBitmap->Height - 1;
|
|||
|
|
rc.Left = XL;
|
|||
|
|
rc.Right = XR;
|
|||
|
|
rc.Top = YT;
|
|||
|
|
rc.Bottom = YB+1;
|
|||
|
|
tp->Brush->Color = clBlack;
|
|||
|
|
tp->FillRect(rc);
|
|||
|
|
XR -= XRD;
|
|||
|
|
|
|||
|
|
int i, x;
|
|||
|
|
if( m_Err || FSKDEM.m_OverFlow ){
|
|||
|
|
if( m_Err || (!m_Tx && !m_Test) ){
|
|||
|
|
tp->Font->Color = clWhite;
|
|||
|
|
tp->Font->Size = 10;
|
|||
|
|
char bf[32];
|
|||
|
|
strcpy(bf, m_Err ? "Lost sound" : "Overflow");
|
|||
|
|
x = tp->TextWidth(bf);
|
|||
|
|
tp->TextOut(XR - x - 3, 0, bf);
|
|||
|
|
}
|
|||
|
|
FSKDEM.m_OverFlow = 0;
|
|||
|
|
if( m_Err ) m_Err--;
|
|||
|
|
}
|
|||
|
|
if( WaveFile.m_mode ){
|
|||
|
|
tp->Font->Color = clWhite;
|
|||
|
|
tp->Font->Size = 10;
|
|||
|
|
if( WaveFile.m_pause ){
|
|||
|
|
tp->TextOut(3, 0, "Pause");
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
switch(WaveFile.m_mode){
|
|||
|
|
case 1:
|
|||
|
|
tp->TextOut(3, 0, "Play");
|
|||
|
|
break;
|
|||
|
|
case 2:
|
|||
|
|
tp->TextOut(3, 0, "Rec.");
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
double space = FSKDEM.GetSpaceFreq();
|
|||
|
|
double mark = FSKDEM.GetMarkFreq();
|
|||
|
|
double shift = fabs(mark - space);
|
|||
|
|
double center = (mark + space)/2.0;
|
|||
|
|
double low;
|
|||
|
|
int FM = GetScopeRange(low, center, shift) + 0.5;
|
|||
|
|
tp->Pen->Color = clYellow;
|
|||
|
|
tp->Pen->Style = psSolid;
|
|||
|
|
x = int(((mark-low)*FFT_SIZE*double(XR)/double(SampFreq*FM)) + 0.5);
|
|||
|
|
tp->MoveTo(x, YT);
|
|||
|
|
tp->LineTo(x, YB);
|
|||
|
|
x = int(((space-low)*FFT_SIZE*double(XR)/double(SampFreq*FM)) + 0.5);
|
|||
|
|
tp->MoveTo(x, YT);
|
|||
|
|
tp->LineTo(x, YB);
|
|||
|
|
|
|||
|
|
if( sw || (!m_FFTSW) ) return 1;
|
|||
|
|
|
|||
|
|
int offx = int((low * FFT_SIZE / SampFreq) + ((FM/XR)/2.0) + 0.5);
|
|||
|
|
tp->Pen->Color = clWhite;
|
|||
|
|
|
|||
|
|
int d;
|
|||
|
|
int max = 0;
|
|||
|
|
double k;
|
|||
|
|
if( sys.m_FFTGain >= 4 ){
|
|||
|
|
switch(sys.m_FFTGain){
|
|||
|
|
case 4:
|
|||
|
|
k = double(YB) * 0.85 / m_FFTMax;
|
|||
|
|
break;
|
|||
|
|
case 5:
|
|||
|
|
k = double(YB) * 1.0 / m_FFTMax;
|
|||
|
|
break;
|
|||
|
|
case 6:
|
|||
|
|
k = double(YB) * 1.2 / m_FFTMax;
|
|||
|
|
break;
|
|||
|
|
case 7:
|
|||
|
|
k = double(YB) * 1.5 / m_FFTMax;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
k = double(YB)/256.0;
|
|||
|
|
}
|
|||
|
|
for( i = 0; i < XR; i++ ){
|
|||
|
|
x = (i * FM)/XR + offx;
|
|||
|
|
if( (x >= 0) && (x < m_FFTWINDOW) ){
|
|||
|
|
d = fftIN.m_fft[x];
|
|||
|
|
if( d > max ) max = d;
|
|||
|
|
d *= k;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
d = 0;
|
|||
|
|
}
|
|||
|
|
if( d >= (YB-YT) ) d = YB - YT - 1;
|
|||
|
|
if( i ){
|
|||
|
|
tp->LineTo(i, YB-d);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
tp->MoveTo(i, YB-d);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if( sys.m_FFTGain >= 4 ){
|
|||
|
|
m_FFTSumMax -= m_FFTMax;
|
|||
|
|
m_FFTSumMax += max;
|
|||
|
|
if( m_FFTSumMax < 64 ) m_FFTSumMax = 64;
|
|||
|
|
m_FFTMax = m_FFTSumMax / 2;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if( m_lmsbpf && m_lms.m_Type ){
|
|||
|
|
if( m_lms.m_lmsNotch ){
|
|||
|
|
tp->Pen->Color = clYellow;
|
|||
|
|
tp->Pen->Style = psSolid;
|
|||
|
|
x = int(((m_lms.m_lmsNotch-low)*FFT_SIZE*double(XR)/double(SampFreq*FM)) + 0.5);
|
|||
|
|
//POINT ary[3]; //JA7UDE 0428
|
|||
|
|
TPoint ary[3]; //JA7UDE 0428
|
|||
|
|
ary[0].x = x, ary[0].y = YB;
|
|||
|
|
ary[1].x = x-3, ary[1].y = YB-5;
|
|||
|
|
ary[2].x = x+3, ary[2].y = YB-5;
|
|||
|
|
tp->Brush->Color = clRed;
|
|||
|
|
tp->Polygon(ary, 2);
|
|||
|
|
if( m_lms.m_twoNotch && m_lms.m_lmsNotch2 ){
|
|||
|
|
x = int(((m_lms.m_lmsNotch2-low)*FFT_SIZE*double(XR)/double(SampFreq*FM)) + 0.5);
|
|||
|
|
ary[0].x = x, ary[0].y = YB;
|
|||
|
|
ary[1].x = x-3, ary[1].y = YB-5;
|
|||
|
|
ary[2].x = x+3, ary[2].y = YB-5;
|
|||
|
|
tp->Brush->Color = clBlue;
|
|||
|
|
tp->Polygon(ary, 2);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return 2;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
double __fastcall TSound::GetScreenFreq(int x, int XW, int XRD)
|
|||
|
|
{
|
|||
|
|
double space = FSKDEM.GetSpaceFreq();
|
|||
|
|
double mark = FSKDEM.GetMarkFreq();
|
|||
|
|
double shift = fabs(mark - space);
|
|||
|
|
double center = (mark + space)/2.0;
|
|||
|
|
double low;
|
|||
|
|
double FW = GetScopeRange(low, center, shift) * SampFreq / FFT_SIZE;
|
|||
|
|
return ((x * FW) / (XW-XRD)) + low;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
// <20>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD><68><EFBFBD>ŃR<C583>[<5B><><EFBFBD><EFBFBD><EFBFBD>Ă͂<C482><CD82><EFBFBD><EFBFBD>Ȃ<EFBFBD>
|
|||
|
|
int __fastcall TSound::DrawFFTWater(Graphics::TBitmap *pBitmap, int sw, int XRD)
|
|||
|
|
{
|
|||
|
|
if( Remote & REMSHOWOFF ) return 2;
|
|||
|
|
TCanvas *tp = pBitmap->Canvas;
|
|||
|
|
TRect rc;
|
|||
|
|
int XL = 0;
|
|||
|
|
int XR = pBitmap->Width - 1;
|
|||
|
|
int YT = 0;
|
|||
|
|
int YB = pBitmap->Height - 1;
|
|||
|
|
rc.Left = XL;
|
|||
|
|
rc.Right = XR;
|
|||
|
|
rc.Top = YT;
|
|||
|
|
rc.Bottom = YB+1;
|
|||
|
|
if( sw ){
|
|||
|
|
tp->Brush->Color = clBlack;
|
|||
|
|
tp->FillRect(rc);
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
int i, x;
|
|||
|
|
int XRR = XR - XRD;
|
|||
|
|
|
|||
|
|
double space = FSKDEM.GetSpaceFreq();
|
|||
|
|
double mark = FSKDEM.GetMarkFreq();
|
|||
|
|
double shift = fabs(mark - space);
|
|||
|
|
double center = (mark + space)/2.0;
|
|||
|
|
double low;
|
|||
|
|
int FM = GetScopeRange(low, center, shift) + 0.5;
|
|||
|
|
|
|||
|
|
TRect src(rc);
|
|||
|
|
src.Bottom--;
|
|||
|
|
rc.Top++;
|
|||
|
|
tp->CopyRect(rc, tp, src);
|
|||
|
|
|
|||
|
|
int offx = int((low * FFT_SIZE / SampFreq) + ((FM/XRR)/2.0) + 0.5);
|
|||
|
|
int d;
|
|||
|
|
int mx = -MAXINT;
|
|||
|
|
int mi = 0;
|
|||
|
|
int micnt = 0;
|
|||
|
|
double k1 = 128.0/double(m_WaterMax - m_WaterMin);
|
|||
|
|
for( i = 0; i < XR; i++ ){
|
|||
|
|
x = (i * FM)/XRR + offx;
|
|||
|
|
if( ((x >= 0) && (x < m_FFTWINDOW)) ){
|
|||
|
|
d = fftIN.m_fft[x] / 2;
|
|||
|
|
if( mx < d ) mx = d;
|
|||
|
|
mi += d;
|
|||
|
|
micnt++;
|
|||
|
|
|
|||
|
|
d -= m_WaterMin;
|
|||
|
|
d = double(d) * k1;
|
|||
|
|
|
|||
|
|
if( d >= 128 ) d = 127;
|
|||
|
|
if( d < 0 ) d = 0;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
d = 0;
|
|||
|
|
}
|
|||
|
|
tp->Pixels[i][0] = TColor(ColorTable[127-d] | sys.d_PaletteMask);
|
|||
|
|
}
|
|||
|
|
m_WaterSumMax -= m_WaterMax;
|
|||
|
|
m_WaterSumMax += mx;
|
|||
|
|
if( sys.m_FFTGain >= 4 ){
|
|||
|
|
if( m_WaterSumMax < (16*2) ) m_WaterSumMax = (16*2);
|
|||
|
|
if( m_WaterSumMax > 512 ) m_WaterSumMax = 512;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if( m_WaterSumMax < (128*2) ) m_WaterSumMax = (128*2);
|
|||
|
|
}
|
|||
|
|
m_WaterMax = m_WaterSumMax / 8;
|
|||
|
|
if( micnt ){
|
|||
|
|
m_WaterMin = mi/micnt;
|
|||
|
|
}
|
|||
|
|
if( sys.m_FFTGain >= 4 ){
|
|||
|
|
if( m_WaterMin >= (m_WaterMax - 4) ) m_WaterMax = m_WaterMin + 4;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
if( m_WaterMin >= (m_WaterMax - 32) ) m_WaterMax = m_WaterMin + 32;
|
|||
|
|
}
|
|||
|
|
return 2;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
//AA6YQ 1.6.6
|
|||
|
|
LPCSTR __fastcall TSound::GetInputSoundcard(unsigned int ID)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
if (MMSYSERR_NOERROR==(waveInGetDevCaps(ID,&InCaps,sizeof(InCaps)))) {
|
|||
|
|
return InCaps.szPname;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
return "";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
//AA6YQ 1.6.6
|
|||
|
|
LPCSTR __fastcall TSound::GetOutputSoundcard(unsigned int ID)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
if (MMSYSERR_NOERROR==(waveOutGetDevCaps(ID,&OutCaps,sizeof(OutCaps)))) {
|
|||
|
|
return OutCaps.szPname;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
return "";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//---------------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
void __fastcall CWaveFile::ReadWrite(double *s, int size)
|
|||
|
|
{
|
|||
|
|
SHORT d;
|
|||
|
|
|
|||
|
|
if( m_Handle != NULL ){
|
|||
|
|
if( m_mode == 2 ){ // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
if( !m_pause ){
|
|||
|
|
for( ; size; s++, size-- ){
|
|||
|
|
d = SHORT(*s);
|
|||
|
|
if( mmioWrite(m_Handle, (const char*)&d, 2) != 2 ){
|
|||
|
|
mmioClose(m_Handle, 0);
|
|||
|
|
m_Handle = 0;
|
|||
|
|
m_mode = 0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_pos += 2;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else { // <20>ǂݏo<DD8F><6F>
|
|||
|
|
if( m_pause || m_dis ){
|
|||
|
|
memset(s, 0, sizeof(double)*size);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
for( ; size; s++, size-- ){
|
|||
|
|
if( mmioRead(m_Handle, (char *)&d, 2) == 2 ){
|
|||
|
|
*s = d;
|
|||
|
|
m_pos += 2;
|
|||
|
|
}
|
|||
|
|
else if( m_autopause ){
|
|||
|
|
m_pause = 1;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
mmioClose(m_Handle, 0);
|
|||
|
|
m_Handle = 0;
|
|||
|
|
m_mode = 0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
for( ; size; s++, size-- ){
|
|||
|
|
*s = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
__fastcall CWaveFile::CWaveFile()
|
|||
|
|
{
|
|||
|
|
m_mode = 0;
|
|||
|
|
m_pause = 0;
|
|||
|
|
m_Handle = NULL;
|
|||
|
|
m_dis = 0;
|
|||
|
|
m_autopause = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
__fastcall CWaveFile::~CWaveFile()
|
|||
|
|
{
|
|||
|
|
FileClose();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void __fastcall CWaveFile::FileClose(void)
|
|||
|
|
{
|
|||
|
|
m_mode = 0;
|
|||
|
|
m_pause = 0;
|
|||
|
|
if( m_Handle != NULL ){
|
|||
|
|
mmioClose(m_Handle, 0);
|
|||
|
|
m_Handle = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void __fastcall CWaveFile::Rec(LPCSTR pName)
|
|||
|
|
{
|
|||
|
|
FileClose();
|
|||
|
|
m_FileName = pName;
|
|||
|
|
m_Handle = mmioOpen(m_FileName.c_str(), NULL, MMIO_CREATE|MMIO_WRITE|MMIO_ALLOCBUF);
|
|||
|
|
if( m_Handle == NULL ){
|
|||
|
|
ErrorMB( (sys.m_WinFontCharset != SHIFTJIS_CHARSET)?"Can't open '%s'":"'%s'<27><><EFBFBD>쐬<EFBFBD>ł<EFBFBD><C582>܂<EFBFBD><DC82><EFBFBD>.", pName);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
m_Head[0] = 0x55;
|
|||
|
|
m_Head[1] = 0xaa;
|
|||
|
|
m_Head[2] = char(SampType);
|
|||
|
|
m_Head[3] = 0;
|
|||
|
|
mmioWrite(m_Handle, (const char *)m_Head, 4);
|
|||
|
|
m_pos = 4;
|
|||
|
|
m_mode = 2;
|
|||
|
|
m_pause = 0;
|
|||
|
|
m_dis = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int SampTable[]={11025, 8000, 6000, 12000, 16000, 18000, 22050, 24000, 44100};
|
|||
|
|
BOOL __fastcall CWaveFile::Play(LPCSTR pName)
|
|||
|
|
{
|
|||
|
|
FileClose();
|
|||
|
|
FILE *fp = fopen(pName, "rb");
|
|||
|
|
if( fp == NULL ){
|
|||
|
|
ErrorMB( (sys.m_WinFontCharset != SHIFTJIS_CHARSET)?"Can't open '%s'":"'%s'<27><><EFBFBD>I<EFBFBD>[<5B>v<EFBFBD><76><EFBFBD>ł<EFBFBD><C582>܂<EFBFBD><DC82><EFBFBD>.", pName);
|
|||
|
|
return FALSE;
|
|||
|
|
}
|
|||
|
|
m_length = filelength(fileno(fp));
|
|||
|
|
m_FileName = pName;
|
|||
|
|
fclose(fp);
|
|||
|
|
m_Handle = mmioOpen(m_FileName.c_str(), NULL, MMIO_READ|MMIO_ALLOCBUF);
|
|||
|
|
if( m_Handle == NULL ){
|
|||
|
|
ErrorMB( (sys.m_WinFontCharset != SHIFTJIS_CHARSET)?"Can't open '%s'":"'%s'<27><><EFBFBD>I<EFBFBD>[<5B>v<EFBFBD><76><EFBFBD>ł<EFBFBD><C582>܂<EFBFBD><DC82><EFBFBD>.", pName);
|
|||
|
|
return FALSE;
|
|||
|
|
}
|
|||
|
|
m_pos = 0;
|
|||
|
|
if( mmioRead(m_Handle, (char *)m_Head, 4) == 4 ){
|
|||
|
|
int type = 0;
|
|||
|
|
if( (m_Head[0] == 0x55)&&(m_Head[1] == 0xaa) ){
|
|||
|
|
type = m_Head[2];
|
|||
|
|
m_pos = 4;
|
|||
|
|
m_length -= 4;
|
|||
|
|
}
|
|||
|
|
if( type > 8 ) type = 0;
|
|||
|
|
if( type != SampType ){
|
|||
|
|
if( YesNoMB(
|
|||
|
|
(sys.m_WinFontCharset != SHIFTJIS_CHARSET)
|
|||
|
|
? "%s\r\n\r\nThis file has been recorded based on %uHz, play it with sampling conversion?"
|
|||
|
|
: "%s\r\n\r\n<EFBFBD><EFBFBD><EFBFBD>̃t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD><EFBFBD> %uHz <20>x<EFBFBD>[<5B>X<EFBFBD>ŋL<C58B>^<5E><><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482>܂<EFBFBD>. <20><><EFBFBD>g<EFBFBD><67><EFBFBD>ϊ<EFBFBD><CF8A><EFBFBD><EFBFBD>čĐ<C48D><C490><EFBFBD><EFBFBD>܂<EFBFBD><DC82><EFBFBD><EFBFBD>H",
|
|||
|
|
m_FileName.c_str(), SampTable[type] ) == IDNO ){
|
|||
|
|
mmioClose(m_Handle, 0);
|
|||
|
|
m_Handle = 0;
|
|||
|
|
return TRUE;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
mmioClose(m_Handle, 0);
|
|||
|
|
m_Handle = 0;
|
|||
|
|
char bf[1024];
|
|||
|
|
strcpy(bf, pName);
|
|||
|
|
SetEXT(bf, "");
|
|||
|
|
char wName[1024];
|
|||
|
|
sprintf(wName, "%s_%u.MMV", bf, int(SampBase));
|
|||
|
|
if( ChangeSampFreq(wName, pName, SampTable[type]) == TRUE ){
|
|||
|
|
Play(wName);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
m_mode = 1;
|
|||
|
|
m_pause = 0;
|
|||
|
|
m_dis = 0;
|
|||
|
|
return TRUE;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void __fastcall CWaveFile::Rewind(void)
|
|||
|
|
{
|
|||
|
|
if( m_Handle != NULL ){
|
|||
|
|
m_dis++;
|
|||
|
|
if( m_mode == 2 ){
|
|||
|
|
mmioSeek(m_Handle, 4, SEEK_SET);
|
|||
|
|
m_pos = 4;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
mmioSeek(m_Handle, 0, SEEK_SET);
|
|||
|
|
m_pos = 0;
|
|||
|
|
}
|
|||
|
|
m_dis--;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void __fastcall CWaveFile::Seek(int n)
|
|||
|
|
{
|
|||
|
|
if( m_Handle != NULL ){
|
|||
|
|
m_dis++;
|
|||
|
|
if( (m_Head[0] == 0x55)&&(m_Head[1] == 0xaa) ){
|
|||
|
|
mmioSeek(m_Handle, n + 4, SEEK_SET);
|
|||
|
|
m_pos = n + 4;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
mmioSeek(m_Handle, n, SEEK_SET);
|
|||
|
|
m_pos = n;
|
|||
|
|
}
|
|||
|
|
m_dis--;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
long __fastcall CWaveFile::GetPos(void)
|
|||
|
|
{
|
|||
|
|
if( (m_Head[0] == 0x55)&&(m_Head[1] == 0xaa) ){
|
|||
|
|
long n = m_pos - 4;
|
|||
|
|
if( n < 0 ) n = 0;
|
|||
|
|
return n;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
return m_pos;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int __fastcall CWaveFile::ChangeSampFreq(LPCSTR tName, LPCSTR pName, int sSamp)
|
|||
|
|
{
|
|||
|
|
int rr = FALSE;
|
|||
|
|
FILE *fp = fopen(pName, "rb");
|
|||
|
|
if( fp != NULL ){
|
|||
|
|
CWaitCursor w;
|
|||
|
|
BYTE head[4];
|
|||
|
|
memset(head, 0, sizeof(head));
|
|||
|
|
head[0] = 0x55;
|
|||
|
|
head[1] = 0xaa;
|
|||
|
|
head[2] = char(SampType);
|
|||
|
|
head[3] = 0;
|
|||
|
|
FILE *wfp = fopen(tName, "wb");
|
|||
|
|
if( wfp != NULL ){
|
|||
|
|
fwrite(head, 1, 4, wfp);
|
|||
|
|
|
|||
|
|
int rsize = 16384;
|
|||
|
|
int wsize = rsize * SampBase/double(sSamp);
|
|||
|
|
short *rp = new short[rsize];
|
|||
|
|
short *wp = new short[wsize];
|
|||
|
|
CIIR riir;
|
|||
|
|
riir.MakeIIR(2800, sSamp, 8, 0, 0);
|
|||
|
|
CIIR wiir;
|
|||
|
|
wiir.MakeIIR(2800, SampBase, 16, 0, 0);
|
|||
|
|
int rlen, wlen;
|
|||
|
|
short *tp;
|
|||
|
|
int i, r;
|
|||
|
|
while(1){
|
|||
|
|
rlen = fread(rp, 1, rsize * 2, fp);
|
|||
|
|
if( !rlen ) break;
|
|||
|
|
rlen /= 2;
|
|||
|
|
if( SampBase < sSamp ){ // <20>f<EFBFBD>V<EFBFBD><56><EFBFBD>[<5B>V<EFBFBD><56><EFBFBD><EFBFBD>
|
|||
|
|
tp = rp;
|
|||
|
|
for( i = 0; i < rlen; i++, tp++ ){
|
|||
|
|
*tp = riir.Do(*tp);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
tp = wp;
|
|||
|
|
wlen = rlen * SampBase / sSamp;
|
|||
|
|
if( wlen > wsize ) wlen = wsize;
|
|||
|
|
for( i = 0; i < wlen; i++ ){
|
|||
|
|
r = int(double(i) * sSamp / SampBase);
|
|||
|
|
*tp++ = wiir.Do(rp[r]);
|
|||
|
|
}
|
|||
|
|
if( fwrite(wp, 1, wlen * 2, wfp) != size_t(wlen * 2) ) break;
|
|||
|
|
}
|
|||
|
|
if( !fclose(wfp) ) rr = TRUE;
|
|||
|
|
delete[] rp;
|
|||
|
|
delete[] wp;
|
|||
|
|
}
|
|||
|
|
fclose(fp);
|
|||
|
|
}
|
|||
|
|
return rr;
|
|||
|
|
}
|
|||
|
|
|