what is wrong with that following code ?
Compiles and executes fine, but doesnt produce any sound... BTW could anyone point me to how produce stereo left and right sound ?
void audio()
{ WAVEHDR _audioHeader;
HWAVEOUT _audioOut = 0;
WAVEFORMATEX _audioStyle;
_audioStyle.wFormatTag = WAVE_FORMAT_PCM;
_audioStyle.nChannels = 1;
_audioStyle.nSamplesPerSec = 44100;
_audioStyle.nAvgBytesPerSec = 44100 * 2;
_audioStyle.nBlockAlign = 2;
_audioStyle.wBitsPerSample = 16;
_audioStyle.cbSize = 0;
_audioHeader.lpData = new char[44100 * 2];
_audioHeader.dwBufferLength = 44100 * 2;
_audioHeader.dwBytesRecorded = 0;
_audioHeader.dwUser = 0;
_audioHeader.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
_audioHeader.dwLoops = 0xFFFF;
_audioHeader.lpNext = NULL;
_audioHeader.reserved = 0;
for(unsigned _x = 0; _x < _audioHeader.dwBufferLength / 2; _x += 2)
{ const
double _byte = 128 + 127 * ::cos(double(_x) * 2.0 * M_PI * double(2400) / double(_audioStyle.nSamplesPerSec));
_audioHeader.lpData[_x + 0] = (char)(_byte);
_audioHeader.lpData[_x + 1] = (char)(_byte);
}
::waveOutOpen(&_audioOut, WAVE_MAPPER, &_audioStyle, NULL, NULL, CALLBACK_NULL);
::waveOutPrepareHeader(&_audioOut, &_audioHeader, sizeof(WAVEHDR));
::waveOutWrite(&_audioOut, &_audioHeader, sizeof(WAVEHDR));
::Beep(1200, 500); ::Sleep(1000); ::Beep(2400, 500);
if(_audioOut != 0)
{ ::waveOutReset(&_audioOut);
::waveOutClose(&_audioOut);
::delete [] _audioHeader.lpData;
}
}
after some research, I found that nBlockAlign has to be computed, wBitsPerSample reduced to 8, and mainly, as waveoutopen requires a pointer to HWAVEOUT, other functions only require the handle….
code became :
{ WAVEHDR _audioHeader;
HWAVEOUT _audioOut = 0;
WAVEFORMATEX _audioStyle;
_audioStyle.wFormatTag = WAVE_FORMAT_PCM;
_audioStyle.nChannels = 2;
_audioStyle.nSamplesPerSec = 44100;
_audioStyle.nAvgBytesPerSec = _audioStyle.nSamplesPerSec * _audioStyle.nChannels;
_audioStyle.wBitsPerSample = 8;
_audioStyle.nBlockAlign = (_audioStyle.wBitsPerSample / 8) * _audioStyle.nChannels;
_audioStyle.cbSize = 0;
_audioHeader.dwBufferLength = _audioStyle.nAvgBytesPerSec;
_audioHeader.lpData = new char[_audioHeader.dwBufferLength];
_audioHeader.dwBytesRecorded = 0;
_audioHeader.dwUser = 0;
_audioHeader.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
_audioHeader.dwLoops = 0xFFFF;
_audioHeader.lpNext = NULL;
_audioHeader.reserved = 0;
for(unsigned _x = 0; _x < _audioHeader.dwBufferLength; _x += 2)
{ const
double _byte = ::cos(double(_x) * 2.0 * M_PI * double(2400) / double(_audioStyle.nSamplesPerSec));
if(_x > (_audioHeader.dwBufferLength / 2))
{ _audioHeader.lpData[_x + 0] = (char)(128 + 127 * 0);
_audioHeader.lpData[_x + 1] = (char)(128 + 127 * _byte);
}
else
{ _audioHeader.lpData[_x + 0] = (char)(128 + 127 * _byte);
_audioHeader.lpData[_x + 1] = (char)(128 + 127 * 0);
}
}
if(::waveOutOpen(&_audioOut, WAVE_MAPPER, &_audioStyle, NULL, NULL, CALLBACK_NULL) == 0)
if(::waveOutPrepareHeader(_audioOut, &_audioHeader, sizeof(WAVEHDR)) == 0)
::waveOutWrite(_audioOut, &_audioHeader, sizeof(WAVEHDR));
::Sleep(1000);
if(_audioOut != 0)
{ ::waveOutReset(_audioOut);
::waveOutClose(_audioOut);
::delete [] _audioHeader.lpData;
}
}
Related
I was inspired by CString class in MFC. After I understood the principle of that class, especially CopyBeforeWrite technology. I attempted to further improve its efficiency. So I wrote an EspString class.
In CString, there is a CStringData for sharing buffer when assigned a already existed CString object to a new one. Specifically, when we wrote CString szNew(szOld) or CString szNew = szOld, initially, they share the same buffer, until one of them is modified (that it will call CopyBeforeWrite function, allocate to a new buffer and allow CStringData::nRef-1).
My code: (most of them are repeated, I inserted the data to struct rather than use (char*)(this+1) to connect).
Storage Struct:
struct EspStringInfo{
/// <summary>
/// > 1 : The buffer is being shared and still can be shared for new string class.
/// = 1 : The buffer can be shared, while it is not shared currently. The initial string will be this value.
/// = -1: The buffer is locked. Although it can be modified, it cannot be shared to any other class.
/// </summary>
long m_nRef;
unsigned int m_nStrLen;
unsigned int m_nBufSize;
char* m_pszStr;};
Two Global Variables:
int g_pNullStringData[] = { -1,0,0,NULL };
EspStringInfo* g_pNullStringInfo = (EspStringInfo*)g_pNullStringData;
Constructor: (Given the character limit, I only provide some of them, while the principle is similar)
EspString(const char& nCh, unsigned int nChCount)
{
assert(nCh != 0);
this->m_pStrInfo = new EspStringInfo;
this->m_pStrInfo->m_nRef = 1;
this->m_pStrInfo->m_nStrLen = nChCount;
this->m_pStrInfo->m_nBufSize = nChCount * 2;
this->m_pStrInfo->m_pszStr = new char[this->m_pStrInfo->m_nBufSize * sizeof(char)];
for (unsigned int I = 0; I < nChCount; ++I)
this->m_pStrInfo->m_pszStr[I] = nCh;
::memset(this->m_pStrInfo->m_pszStr + this->m_pStrInfo->m_nStrLen, 0, (this->m_pStrInfo->m_nBufSize - this->m_pStrInfo->m_nStrLen) * sizeof(char));
}
EspString(const EspString& szStr)
{
if (szStr.m_pStrInfo == g_pNullStringInfo)
{
this->m_pStrInfo = g_pNullStringInfo;
return;
}
if (szStr.m_pStrInfo->m_nRef >= 1)
{
this->m_pStrInfo = szStr.m_pStrInfo;
::InterlockedIncrement(&szStr.m_pStrInfo->m_nRef);
}
else
{
unsigned int nBufSize = szStr.m_pStrInfo->m_nStrLen * 2;
this->m_pStrInfo = new EspStringInfo;
this->m_pStrInfo->m_nRef = 1;
this->m_pStrInfo->m_nStrLen = szStr.m_pStrInfo->m_nStrLen;
this->m_pStrInfo->m_nBufSize = nBufSize;
this->m_pStrInfo->m_pszStr = new char[nBufSize * sizeof(char)];
::memcpy(this->m_pStrInfo->m_pszStr, szStr.m_pStrInfo->m_pszStr, szStr.m_pStrInfo->m_nStrLen * sizeof(char));
::memset(this->m_pStrInfo->m_pszStr + szStr.m_pStrInfo->m_nStrLen, 0, (nBufSize - szStr.m_pStrInfo->m_nStrLen) * sizeof(char));
}
}
Destructor:
~EspString()
{
if (this->m_pStrInfo != g_pNullStringInfo)
{
if (::InterlockedDecrement(&this->m_pStrInfo->m_nRef) < 1)
{
delete[] this->m_pStrInfo->m_pszStr;
delete this->m_pStrInfo;
}
}
}
Append: (e.g. szStr="1234"; szStr.Append("56") and then szStr="123456" )
EspString& Append(const char& nCh, unsigned int nCount)
{
if (nCh == 0)
return *this;
if (this->m_pStrInfo == g_pNullStringInfo)
{
this->m_pStrInfo = new EspStringInfo;
this->m_pStrInfo->m_nRef = 1;
this->m_pStrInfo->m_nStrLen = nCount;
this->m_pStrInfo->m_nBufSize = nCount * 2;
this->m_pStrInfo->m_pszStr = new char[this->m_pStrInfo->m_nBufSize * sizeof(char)];
::memset(this->m_pStrInfo->m_pszStr, nCh, nCount * sizeof(char));
::memset(this->m_pStrInfo->m_pszStr + nCount, 0, nCount * sizeof(char));
}
else
{
unsigned int nStrLen = this->m_pStrInfo->m_nStrLen + nCount;
if (this->m_pStrInfo->m_nRef > 1)
{
unsigned int nBufSize = nStrLen * 2;
EspStringInfo* pNewStrInfo = new EspStringInfo;
pNewStrInfo->m_nRef = 1;
pNewStrInfo->m_nStrLen = nStrLen;
pNewStrInfo->m_nBufSize = nBufSize;
pNewStrInfo->m_pszStr = new char[nBufSize * sizeof(char)];
::memcpy(pNewStrInfo->m_pszStr, this->m_pStrInfo->m_pszStr, this->m_pStrInfo->m_nStrLen * sizeof(char));
::memset(pNewStrInfo->m_pszStr + this->m_pStrInfo->m_nStrLen, nCh, nCount * sizeof(char));
::memset(pNewStrInfo->m_pszStr + nStrLen, 0, (nBufSize - nStrLen) * sizeof(char));
::InterlockedDecrement(&this->m_pStrInfo->m_nRef);
this->m_pStrInfo = pNewStrInfo;
}
else
{
if (nStrLen < this->m_pStrInfo->m_nBufSize)
{
::memset(this->m_pStrInfo->m_pszStr + this->m_pStrInfo->m_nStrLen, nCh, nCount * sizeof(char));
this->m_pStrInfo->m_nStrLen = nStrLen;
}
else
{
unsigned int nBufSize = nStrLen * 2;
char* pszNewBuf = new char[nBufSize * sizeof(char)];
::memcpy(pszNewBuf, this->m_pStrInfo->m_pszStr, this->m_pStrInfo->m_nStrLen * sizeof(char));
::memset(pszNewBuf + this->m_pStrInfo->m_nStrLen, nCh, nCount * sizeof(char));
::memset(pszNewBuf + nStrLen, 0, (nBufSize - nStrLen) * sizeof(char));
delete[] this->m_pStrInfo->m_pszStr;
this->m_pStrInfo->m_nStrLen = nStrLen;
this->m_pStrInfo->m_nBufSize = nBufSize;
this->m_pStrInfo->m_pszStr = pszNewBuf;
}
}
}
return *this;
}
EspString& Append(const char* pszStr)
{
if (pszStr == NULL)
return *this;
unsigned int nNewStrLen = ::lstrlenA(pszStr);
if (this->m_pStrInfo == g_pNullStringInfo)
{
this->m_pStrInfo = new EspStringInfo;
this->m_pStrInfo->m_nRef = 1;
this->m_pStrInfo->m_nStrLen = nNewStrLen;
this->m_pStrInfo->m_nBufSize = nNewStrLen * 2;
this->m_pStrInfo->m_pszStr = new char[this->m_pStrInfo->m_nBufSize * sizeof(char)];
::memcpy(this->m_pStrInfo->m_pszStr, pszStr, nNewStrLen * sizeof(char));
::memset(this->m_pStrInfo->m_pszStr + nNewStrLen, 0, nNewStrLen * sizeof(char));
}
else
{
unsigned int nStrLen = this->m_pStrInfo->m_nStrLen + nNewStrLen;
if (this->m_pStrInfo->m_nRef > 1)
{
unsigned int nBufSize = nStrLen * 2;
EspStringInfo* pNewStrInfo = new EspStringInfo;
pNewStrInfo->m_nRef = 1;
pNewStrInfo->m_nStrLen = nStrLen;
pNewStrInfo->m_nBufSize = nBufSize;
pNewStrInfo->m_pszStr = new char[nBufSize * sizeof(char)];
::memcpy(pNewStrInfo->m_pszStr, this->m_pStrInfo->m_pszStr, this->m_pStrInfo->m_nStrLen * sizeof(char));
::memcpy(pNewStrInfo->m_pszStr + this->m_pStrInfo->m_nStrLen, pszStr, nNewStrLen * sizeof(char));
::memset(pNewStrInfo->m_pszStr + nStrLen, 0, (nBufSize - nStrLen) * sizeof(char));
::InterlockedDecrement(&this->m_pStrInfo->m_nRef);
this->m_pStrInfo = pNewStrInfo;
}
else
{
if (nStrLen < this->m_pStrInfo->m_nBufSize)
{
::memcpy(this->m_pStrInfo->m_pszStr + this->m_pStrInfo->m_nStrLen, pszStr, nNewStrLen * sizeof(char));
this->m_pStrInfo->m_nStrLen = nStrLen;
}
else
{
unsigned int nBufSize = nStrLen * 2;
char* pszNewBuf = new char[nBufSize * sizeof(char)];
::memcpy(pszNewBuf, this->m_pStrInfo->m_pszStr, this->m_pStrInfo->m_nStrLen * sizeof(char));
::memcpy(pszNewBuf + this->m_pStrInfo->m_nStrLen, pszStr, nNewStrLen * sizeof(char));
::memset(pszNewBuf + nStrLen, 0, (nBufSize - nStrLen) * sizeof(char));
delete[] this->m_pStrInfo->m_pszStr;
this->m_pStrInfo->m_nStrLen = nStrLen;
this->m_pStrInfo->m_nBufSize = nBufSize;
this->m_pStrInfo->m_pszStr = pszNewBuf;
}
}
}
return *this;
}
EspString& Append(const EspString& szStr)
{
if (szStr.m_pStrInfo == g_pNullStringInfo)
return *this;
unsigned int nNewStrLen = szStr.m_pStrInfo->m_nStrLen;
if (this->m_pStrInfo == g_pNullStringInfo)
{
this->m_pStrInfo = new EspStringInfo;
this->m_pStrInfo->m_nRef = 1;
this->m_pStrInfo->m_nStrLen = nNewStrLen;
this->m_pStrInfo->m_nBufSize = nNewStrLen * 2;
this->m_pStrInfo->m_pszStr = new char[this->m_pStrInfo->m_nBufSize * sizeof(char)];
::memcpy(this->m_pStrInfo->m_pszStr, szStr.m_pStrInfo->m_pszStr, nNewStrLen * sizeof(char));
::memset(this->m_pStrInfo->m_pszStr + nNewStrLen, 0, nNewStrLen * sizeof(char));
}
else
{
unsigned int nStrLen = this->m_pStrInfo->m_nStrLen + nNewStrLen;
if (this->m_pStrInfo->m_nRef > 1)
{
unsigned int nBufSize = nStrLen * 2;
EspStringInfo* pNewStrInfo = new EspStringInfo;
pNewStrInfo->m_nRef = 1;
pNewStrInfo->m_nStrLen = nStrLen;
pNewStrInfo->m_nBufSize = nBufSize;
pNewStrInfo->m_pszStr = new char[nBufSize * sizeof(char)];
::memcpy(pNewStrInfo->m_pszStr, this->m_pStrInfo->m_pszStr, this->m_pStrInfo->m_nStrLen * sizeof(char));
::memcpy(pNewStrInfo->m_pszStr + this->m_pStrInfo->m_nStrLen, szStr.m_pStrInfo->m_pszStr, nNewStrLen * sizeof(char));
::memset(pNewStrInfo->m_pszStr + nStrLen, 0, (nBufSize - nStrLen) * sizeof(char));
::InterlockedDecrement(&this->m_pStrInfo->m_nRef);
this->m_pStrInfo = pNewStrInfo;
}
else
{
if (nStrLen < this->m_pStrInfo->m_nBufSize)
{
::memcpy(this->m_pStrInfo->m_pszStr + this->m_pStrInfo->m_nStrLen, szStr.m_pStrInfo->m_pszStr, nNewStrLen * sizeof(char));
this->m_pStrInfo->m_nStrLen = nStrLen;
}
else
{
unsigned int nBufSize = nStrLen * 2;
char* pszNewBuf = new char[nBufSize * sizeof(char)];
::memcpy(pszNewBuf, this->m_pStrInfo->m_pszStr, this->m_pStrInfo->m_nStrLen * sizeof(char));
::memcpy(pszNewBuf + this->m_pStrInfo->m_nStrLen, szStr.m_pStrInfo->m_pszStr, nNewStrLen * sizeof(char));
::memset(pszNewBuf + nStrLen, 0, (nBufSize - nStrLen) * sizeof(char));
delete[] this->m_pStrInfo->m_pszStr;
this->m_pStrInfo->m_nStrLen = nStrLen;
this->m_pStrInfo->m_nBufSize = nBufSize;
this->m_pStrInfo->m_pszStr = pszNewBuf;
}
}
}
return *this;
}
There are also some other method, and there is the general process:
Judge the m_pStrInfo is g_pNullStringInfo, all null string will point to this pointer.
if m_nRef>1, the buffer is being shared.
the buffer is not shared.
I wrote this project because in my project the string class have to be assigned to a new object for a lots of times. In the past, the buffer has to be allocated repeatedly and it will waste lots of resources and time. Have there some ways to further improve the efficiency? Thanks for the reply!!!!!!!
I'm trying to implement a FIR filter low-pass windowed, but the result is not consistent.
Here is my code:
#define N_FIR 51
main() {
FILE* fin;
FILE* fout = NULL;
short *data16bits = NULL;
fin = fopen("file3.wav", "rb");
fread(&wavHeader, sizeof(wav_hdr), 1, fin);
data16bits = (short*)malloc(wavHeader.subChunk2Size * sizeof(short));
fread(data16bits, wavHeader.bitsPerSample, wavHeader.subChunk2Size / 2, fin);
fclose(fin);
fout = fopen("FIRfilterLowPass.wav", "wb");
fwrite(&wavHeader, sizeof(wav_hdr), 1, fout);
double *fltr = (double *)malloc(N_FIR * sizeof(double));
FIRfilterLowPass(1000, wavHeader.sampleRate, fltr);
for (size_t i = 0; i < wavHeader.subChunk2Size; i++) {
double result = 0;
short result_short = 0;
for (size_t j = 0; j < N_FIR && (i - j) >= 0; j++) {
result += fltr[j] * data16bits[i - j];
}
result_short = (short)result;
fwrite(&result_short, sizeof(short), 1, fout);
}
}
void FIRfilterLowPass(double f_c, double f_samp, double* fltr) {
f_c = f_c / f_samp;
double w_c = 2 * PI * f_c;
int middle = N_FIR / 2;
for (int n = -N_FIR / 2; n <= N_FIR / 2; n++) {
if (n == 0) {
fltr[middle] = 2 * f_c;
}
else {
fltr[middle + n] = sin(2 * PI * f_c * n) / (PI * n);
}
}
for (int n = 0; n < N_FIR; n++) {
fltr[n] = fltr[n] * (0.5f + 0.5f * cos((2 * PI * n) / N_FIR));
}
}
What am I doing wrong, because the wave looks like this:
But it should look more like this:
Thank you for your time!
I am receiving data in TCP in C++ using Qt library. I store the received packet in a QByteArray, but after reading the whole data, I face this error in debug. At the end, I try to clear the buffer, but I face this problem while trying to clear it too.
Here is my code :
void AvaNPortTester::scoket_readyRead()
{
ui.lineEdit_Sending_Status_->setText("Sent");
ui.lineEdit_Sending_Status_->setStyleSheet("QLineEdit { background: rgb(50, 255, 50); }");
tcpSocket_data_buffer_.append(tcpSocket_->readAll());
//qDebug() << serialport_data_buffer_.size();
//auto ddd = QString::number(tcpSocket_data_buffer_.size());// +" : " + tcpSocket_data_buffer_.toHex();
//ui.lableSocketRead->setText(ddd);
bool read_aain = false;
QByteArray dummy(int(1446), Qt::Initialization::Uninitialized);
int reminded_data = 0;
int dummy_size = 0;
int frame_size = 0;
int l_size = 0;
int total_size_rcvd = tcpSocket_data_buffer_.size();
//int total_size_rcvd_b = total_size_rcvd_b;
int temp = 0;
while (total_size_rcvd != 0)
{
if(total_size_rcvd != 0){
auto packet = tcpSocket_data_buffer_.mid(0, 1446);
auto rem = tcpSocket_data_buffer_.mid(1446);//****1146
tcpSocket_data_buffer_ = rem;
QDataStream streamdata(packet);
uint8_t Sync_Header[3];
auto ss = streamdata.readRawData((char*)&Sync_Header, 3);
uint8_t Total_size[2];
ss = streamdata.readRawData((char*)&Total_size, 2);
int t_size = Total_size[0] * 256 + Total_size[1];
uint8_t Reserved[2];
ss = streamdata.readRawData((char*)&Reserved, 2);
frame_size = t_size - 2;
reminded_data = t_size - 2;
while (frame_size != 0)
{
uint8_t portid;
ss = streamdata.readRawData((char*)&portid, 1);
//ui.lineEdit_FileSize->setText(QString::number(fileSend_2Ser->size()));
uint8_t ProtocolID;
ss = streamdata.readRawData((char*)&ProtocolID, 1);
uint8_t MoreFragmentFlag;
ss = streamdata.readRawData((char*)&MoreFragmentFlag, 1);
uint8_t Seq;
ss = streamdata.readRawData((char*)&Seq, 1);
uint8_t size[2];
ss = streamdata.readRawData((char*)&size, 2);
l_size = size[0] * 256 + size[1];
if (packet_flags.Ser2Eth.packet_started[portid] == false) {
uint8_t DDCMP_Header[14];
ss = streamdata.readRawData((char*)&DDCMP_Header, 14);
packet_flags.Ser2Eth.protocol_payload_size[portid] = DDCMP_Header[7] + 256 * DDCMP_Header[8];
temp = packet_flags.Ser2Eth.protocol_payload_size[portid];
packet_flags.Ser2Eth.packet_started[portid] = true;
}
QByteArray ddcmp_datap(int(l_size), Qt::Initialization::Uninitialized);
streamdata.readRawData(ddcmp_datap.data(), l_size - 14);
if ((pre_more_frag == 0) && (MoreFragmentFlag == 0)) {
packet_flags.Ser2Eth.packet_ended[portid] = true;
packet_flags.Ser2Eth.protocol_payload_size[portid] = l_size;
temp = packet_flags.Ser2Eth.protocol_payload_size[portid];
}
else if ((pre_more_frag == 0) && (MoreFragmentFlag == 1)) {
packet_flags.Ser2Eth.packet_ended[portid] = false;
packet_flags.Ser2Eth.protocol_payload_size[portid] = l_size + 16;
temp = packet_flags.Ser2Eth.protocol_payload_size[portid];
}
else if ((pre_more_frag == 1) && (MoreFragmentFlag == 1)) {
packet_flags.Ser2Eth.packet_ended[portid] = false;
packet_flags.Ser2Eth.protocol_payload_size[portid] = packet_flags.Ser2Eth.protocol_payload_size[portid] + l_size;
temp = packet_flags.Ser2Eth.protocol_payload_size[portid];
}
else if ((pre_more_frag == 1) && (MoreFragmentFlag == 0)) {
packet_flags.Ser2Eth.packet_ended[portid] = true;
packet_flags.Ser2Eth.protocol_payload_size[portid] = packet_flags.Ser2Eth.protocol_payload_size[portid] + l_size;
temp = packet_flags.Ser2Eth.protocol_payload_size[portid];
}
if (MoreFragmentFlag == 1) {
pre_more_frag = 1;
}
else {
pre_more_frag = 0;
}
int ff = 0;
if (packet_flags.Ser2Eth.packet_ended[portid] == true) {
packet_flags.Ser2Eth.packet_started[portid] = false;
packet_flags.Ser2Eth.packet_started[portid] = false;
set_port_id_flag(portid, packet_flags.Ser2Eth.protocol_payload_size[portid], ProtocolID);
pre_more_frag = 0;
}
reminded_data = reminded_data - 6 - l_size;
//ui.lableSocketRead->setText(ddcmp_datap.toHex());
frame_size = frame_size - l_size - 6;
}//end of while (frame_size != 0)
uint8_t sync_footer[3];
streamdata.readRawData((char *)&sync_footer, 3);
dummy_size = 1446 - t_size - 8;
uint8_t dummy_data[1000];
streamdata.readRawData((char *)&dummy_data, dummy_size);
total_size_rcvd = total_size_rcvd - 1446;
if (total_size_rcvd == 0) {
tcpSocket_data_buffer_.clear();
}
} //end of if
}//end of while()
}
iam writing a program to represent a blur efect on a bitmap.
Blur efect code:
for (xx = 0; xx < bitmapInfoHeader.biWidth; xx++)
{
for (yy = 0; yy <bitmapInfoHeader.biHeight; yy++)
{
avgB = avgG = avgR = 0;
Counter = 0;
for (x = xx; x < bitmapInfoHeader.biWidth && x < xx + blurSize; x++)
{
for (y = yy; y < bitmapInfoHeader.biHeight && y < yy + blurSize; y++)
{
avgB += bitmapImage[x *3 + y*bitmapInfoHeader.biWidth * 3 + 0]; //bitmapimage[x][y];
avgG += bitmapImage[x *3 + y*bitmapInfoHeader.biWidth * 3 + 1];
avgR += bitmapImage[x *3 + y*bitmapInfoHeader.biWidth * 3 + 2];
Counter++;
}
}
avgB = avgB / Counter;
avgG = avgG / Counter;
avgR = avgR / Counter;
bitmapImage[xx * 3 + yy*bitmapInfoHeader.biWidth * 3 + 0] = avgB;
bitmapImage[xx * 3 + yy*bitmapInfoHeader.biWidth * 3 + 1] = avgG;
bitmapImage[xx * 3 + yy*bitmapInfoHeader.biWidth * 3 + 2] = avgR;
}
}
And my output function which take the blured Array "bitmapImage" to a new file:
out = fopen(file,"wb");
fwrite(&bitmapInfoHeader, sizeof(char), sizeof(BITMAPINFOHEADER), out);
fwrite(&bitmapFileHeader, sizeof(char), sizeof(BITMAPFILEHEADER), out);
fseek(out, sizeof(char)*bitmapFileHeader.bfOffBits, SEEK_SET);
fwrite(bitmapImage, sizeof(char), bitmapInfoHeader.biSizeImage, out);
The reading function:
BITMAPINFOHEADER bitmapInfoHeader;
FILE *filePtr,*out;
BITMAPFILEHEADER bitmapFileHeader;
unsigned char *bitmapImage = nullptr;
filePtr = fopen(filename, "rb");
if (filePtr == NULL)
return NULL;
fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, filePtr);
fread(&bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, filePtr);
fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);
//bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);
bitmapImage = new unsigned char[bitmapInfoHeader.biSizeImage];
fread(bitmapImage, sizeof(char), bitmapInfoHeader.biSizeImage,filePtr);
*size = bitmapInfoHeader.biSizeImage;
When i compile the program a new bmp file is created but the image viewer cant show it and thorw an error.
So what am doing wrong here? is the blur algorytm good?
I'm trying to update a 128x128 D3DLOCKED_RECT with sub images using the following code, but it seems to squish them down along the top, the X offset is ignored and the y offset is 60 percent off.
I've also tried to make the texture the correct size and copy it into a 128x128 texture at the correct location using RECT, however this is very slow and didn't seem to work correctly when I attempted it. There must be way to do it using the raw pixel data?
Any help would be much appreciated :)
EDIT: I got it semi working using the below code, the locations are now correct and the sizes. But it's only using the blue channel and everything is grey scale (blue scale?)
srcdata = (byte *) pixels;
dstdata = (unsigned int *)lockrect.pBits;
for (y = yoffset; y < (yoffset + height); y++)
{
for (x = xoffset; x < (xoffset + width); x++)
{
dstdata[ ( y * lockrect.Pitch / dstbytes + x ) + 0] = (unsigned int)srcdata[0];
dstdata[ ( y * lockrect.Pitch / dstbytes + x ) + 1] = (unsigned int)srcdata[1];
dstdata[ ( y * lockrect.Pitch / dstbytes + x ) + 2] = (unsigned int)srcdata[0];
dstdata[ ( y * lockrect.Pitch / dstbytes + x ) + 3] = (unsigned int)srcdata[3];
srcdata += srcbytes;
}
}'
END Edit
Test call after creating the 128x128 texture:
int x, y;
byte temp[132*132*4];
// Test texture (pink and black checker)
for( y = 0; y < 16; y++ )
{
for( x = 0; x < 16; x++ )
{
if(( y < 8 ) ^ ( x < 8 ))
((uint *)&temp)[y*16+x] = 0xFFFF00FF;
else ((uint *)&temp)[y*16+x] = 0xFF000000;
}
}
UpdateSubImage (0, 0, 16, 16, temp )
The update Fuction:
void UpdateSubImage (int xoffset, int yoffset, int width, int height, const
GLvoid *pixels)
{
int x, y;
int srcbytes = 4; //Hard coded for now, as all tests are RGBA
int dstbytes = 4; // ^
byte *srcdata;
byte *dstdata;
D3DLOCKED_RECT lockrect;
pTexture->LockRect( 0, &lockrect, NULL, 0);
srcdata = (byte *) pixels;
dstdata = (byte *) lockrect.pBits;
dstdata += (yoffset * width + xoffset) * dstbytes;
for (y = yoffset; y < (yoffset + height); y++)
{
for (x = xoffset; x < (xoffset + width); x++)
{
if (srcbytes == 1)
{
if (dstbytes == 1)
dstdata[0] = srcdata[0];
else if (dstbytes == 4)
{
dstdata[0] = srcdata[0];
dstdata[1] = srcdata[0];
dstdata[2] = srcdata[0];
dstdata[3] = srcdata[0];
}
}
else if (srcbytes == 3)
{
if (dstbytes == 1)
dstdata[0] = ((int) srcdata[0] + (int) srcdata[1] + (int) srcdata[2]) / 3;
else if (dstbytes == 4)
{
dstdata[0] = srcdata[2];
dstdata[1] = srcdata[1];
dstdata[2] = srcdata[0];
dstdata[3] = 255;
}
}
else if (srcbytes == 4)
{
if (dstbytes == 1)
dstdata[0] = ((int) srcdata[0] + (int) srcdata[1] + (int) srcdata[2]) / 3;
else if (dstbytes == 4)
{
dstdata[0] = srcdata[2];
dstdata[1] = srcdata[1];
dstdata[2] = srcdata[0];
dstdata[3] = srcdata[3];
}
}
// advance
srcdata += srcbytes;
dstdata += dstbytes;
}
}
pTexture->UnlockRect(0);
}
What the output looks like:
What the output should look like:
You're assuming that the data accessable through lockrect.pBits is linear in memory. This is in general not the case. Instead you have a constant offset between your rows which is defined by the lockrect.Pitch value.
To get the address of a pixel in the destination use:
byte * destAddr = (lockrect.pBits + y * lockrect.Pitch + 4 * x);
// for 32 bit images. For other formats adjust the hard-coded 4.
Thanks for the help :), in the end the following code worked:
Can it be made faster?
for (y = yoffset; y < (yoffset + height); y++)
{
for (x = xoffset; x < (xoffset + width); x++)
{
ARGB pixel;
pixel.r = srcdata[0];
pixel.g = srcdata[1];
pixel.b = srcdata[2];
pixel.a = srcdata[3];
memcpy( &dstdata[lockrect.Pitch * y + dstbytes * x], &pixel, dstbytes );
srcdata += srcbytes;
}
}