Error while initializing FMOD - c++

Im having a weird issue while initializing FMOD, FMOD enters in some kind of 'infinite loop' and the program stops. What i'm doing wrong?
This is the function:
FMOD::System *fmodsyst = 0;
FMOD::Sound *sound = 0;
FMOD::Channel *channel = 0;
FMOD_RESULT result = FMOD_OK;
unsigned int version = 0;
unsigned int soundlength = 0;
bool dspenabled = false;
void *extradriverdata = 0;
unsigned int recordpos = 0;
unsigned int recorddelta = 0;
unsigned int minrecorddelta = (unsigned int)-1;
unsigned int lastrecordpos = 0;
unsigned int samplesrecorded = 0;
unsigned int playpos = 0;
float smootheddelta = 0;
int recordrate = 0;
int recordchannels = 0;
unsigned int adjustedlatency = 0;
unsigned int driftthreshold = 0;
FMOD_CREATESOUNDEXINFO exinfo;
bool Basics::InitializeFMOD()
{
FMOD_RESULT result;
unsigned int version;
result = FMOD::System_Create(&fmodsyst);
FMOD_ERRCHECK(result);
result = fmodsyst->getVersion(&version);
FMOD_ERRCHECK(result);
if (version < FMOD_VERSION)
{
return false;
}
result = fmodsyst->init(100, FMOD_INIT_NORMAL, extradriverdata); //this is the line which crashes the .dll
FMOD_ERRCHECK(result);
result = fmodsyst->getRecordDriverInfo(0, NULL, NULL, 0, 0, &recordrate, 0, &recordchannels);
FMOD_ERRCHECK(result);
adjustedlatency = (recordrate * LATENCY_MS) / 1000;
driftthreshold = adjustedlatency / 2;
memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
exinfo.numchannels = recordchannels;
exinfo.format = FMOD_SOUND_FORMAT_PCM16;
exinfo.defaultfrequency = recordrate;
exinfo.length = exinfo.defaultfrequency * sizeof(short)* exinfo.numchannels * 5; /* 5 second buffer, doesnt really matter how big this is, but not too small of course. */
result = fmodsyst->createSound(0, FMOD_LOOP_NORMAL | FMOD_OPENUSER, &exinfo, &sound);
FMOD_ERRCHECK(result);
result = fmodsyst->recordStart(0, sound, true);
FMOD_ERRCHECK(result);
result = sound->getLength(&soundlength, FMOD_TIMEUNIT_PCM);
FMOD_ERRCHECK(result);
return true;
}
Also the function FMOD_ERRCHECK doesnt say anything.

It might be that you want FMOD_STUDIO_INIT_NORMAL instead of FMOD_INIT_NORMAL because you are, in fact, initializing the Studio component and not the low level audio system (at least not via that pointer).
We may have different versions, as mine requires an extra parameter:
_pAudioSystem->initialize(32, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, nullptr);

Related

libe57 read file 65536 points

I compiled the libe57 in order to use it in my project. I did it and now I'm trying to use it. (I'm on windows 10 x64)
Basing on this tutorial, I did this
int
main(int argc, char** argv)
{
char sFile[] = "PTX/file.e57";
_bstr_t bsFile = sFile; //converts Unicode to UTF-8
e57::Reader eReader((char*)bsFile);
e57::E57Root rootHeader;
eReader.GetE57Root(rootHeader);
const char* fileGuid = rootHeader.guid.c_str();
e57::DateTime fileGPSTime = rootHeader.creationDateTime;
int data3DCount = eReader.GetData3DCount();
int scanIndex = 0;
e57::Data3D scanHeader;
eReader.ReadData3D(scanIndex, scanHeader);
_bstr_t bstrName = scanHeader.name.c_str();
_bstr_t bstrGuid = scanHeader.guid.c_str();
_bstr_t bstrDesc = scanHeader.description.c_str();
int64_t nColumn = 0;
int64_t nRow = 0;
int64_t nPointsSize = 0; //Number of points
int64_t nGroupsSize = 0; //Number of groups
int64_t nCountSize = 0; //Number of points per group
bool bColumnIndex = false; //indicates that idElementName is "columnIndex"
eReader.GetData3DSizes(scanIndex, nRow, nColumn, nPointsSize, nGroupsSize, nCountSize, bColumnIndex);
int64_t nSize = nRow;
if (nSize == 0) nSize = 1024; // choose a chunk size
int8_t * isInvalidData = NULL;
if (scanHeader.pointFields.cartesianInvalidStateField)
isInvalidData = new int8_t[nSize];
double * xData = NULL;
if (scanHeader.pointFields.cartesianXField)
xData = new double[nSize];
double * yData = NULL;
if (scanHeader.pointFields.cartesianYField)
yData = new double[nSize];
double * zData = NULL;
if (scanHeader.pointFields.cartesianZField)
zData = new double[nSize];
double * intData = NULL;
bool bIntensity = false;
double intRange = 0;
double intOffset = 0;
if (scanHeader.pointFields.intensityField)
{
bIntensity = true;
intData = new double[nSize];
intRange = scanHeader.intensityLimits.intensityMaximum - scanHeader.intensityLimits.intensityMinimum;
intOffset = scanHeader.intensityLimits.intensityMinimum;
}
uint16_t * redData = NULL;
uint16_t * greenData = NULL;
uint16_t * blueData = NULL;
bool bColor = false;
int32_t colorRedRange = 1;
int32_t colorRedOffset = 0;
int32_t colorGreenRange = 1;
int32_t colorGreenOffset = 0;
int32_t colorBlueRange = 1;
int32_t colorBlueOffset = 0;
if (scanHeader.pointFields.colorRedField)
{
bColor = true;
redData = new uint16_t[nSize];
greenData = new uint16_t[nSize];
blueData = new uint16_t[nSize];
colorRedRange = scanHeader.colorLimits.colorRedMaximum - scanHeader.colorLimits.colorRedMinimum;
colorRedOffset = scanHeader.colorLimits.colorRedMinimum;
colorGreenRange = scanHeader.colorLimits.colorGreenMaximum - scanHeader.colorLimits.colorGreenMinimum;
colorGreenOffset = scanHeader.colorLimits.colorGreenMinimum;
colorBlueRange = scanHeader.colorLimits.colorBlueMaximum - scanHeader.colorLimits.colorBlueMinimum;
colorBlueOffset = scanHeader.colorLimits.colorBlueMinimum;
}
int64_t * idElementValue = NULL;
int64_t * startPointIndex = NULL;
int64_t * pointCount = NULL;
if (nGroupsSize > 0)
{
idElementValue = new int64_t[nGroupsSize];
startPointIndex = new int64_t[nGroupsSize];
pointCount = new int64_t[nGroupsSize];
if (!eReader.ReadData3DGroupsData(scanIndex, nGroupsSize, idElementValue,
startPointIndex, pointCount))
nGroupsSize = 0;
}
int32_t * rowIndex = NULL;
int32_t * columnIndex = NULL;
if (scanHeader.pointFields.rowIndexField)
rowIndex = new int32_t[nSize];
if (scanHeader.pointFields.columnIndexField)
columnIndex = new int32_t[nRow];
e57::CompressedVectorReader dataReader = eReader.SetUpData3DPointsData(
scanIndex, //!< data block index given by the NewData3D
nRow, //!< size of each of the buffers given
xData, //!< pointer to a buffer with the x data
yData, //!< pointer to a buffer with the y data
zData, //!< pointer to a buffer with the z data
isInvalidData, //!< pointer to a buffer with the valid indication
intData, //!< pointer to a buffer with the lidar return intesity
NULL,
redData, //!< pointer to a buffer with the color red data
greenData, //!< pointer to a buffer with the color green data
blueData, //!< pointer to a buffer with the color blue data
NULL,
NULL,
NULL,
NULL,
NULL,
rowIndex, //!< pointer to a buffer with the rowIndex
columnIndex //!< pointer to a buffer with the columnIndex
);
int64_t count = 0;
unsigned size = 0;
int col = 0;
int row = 0;
int cpt = 0;
while (size = dataReader.read())
{
cpt++;
}
std::cout << cpt << std::endl;
dataReader.close();
if (isInvalidData) delete isInvalidData;
if (xData) delete xData;
if (yData) delete yData;
if (zData) delete zData;
if (intData) delete intData;
if (redData) delete redData;
if (greenData) delete greenData;
if (blueData) delete blueData;
}
The problem is that everytime, the reader says that there are 65536 rows and 1 cols, meaning that my pointcloud contain always 65536 points. I tried with several files that have more than 200k points each, but the result are always the same, it writes in my XYZ file 65536 points, and no more.
EDIT 2: shorter example : the problem is still the same
#include "E57Foundation.h"
#include "E57Simple.h"
#include "comutil.h"
#include <iostream>
#include <vector>
int
main(int argc, char** argv)
{
e57::Reader eReader("PTX/file.e57");
int scanIndex = 0; //picking the first scan
e57::Data3D scanHeader; //read scan's header information
eReader.ReadData3D(scanIndex, scanHeader);
_bstr_t scanGuid = scanHeader.guid.c_str(); //get guid
int64_t nColumn = 0; //Number of Columns in a structure scan (from "indexBounds" if structure data)
int64_t nRow = 0; //Number of Rows in a structure scan
int64_t nPointsSize = 0; //Number of points
int64_t nGroupsSize = 0; //Number of groups (from "groupingByLine" if present)
int64_t nCountsSize = 0; //Number of points per group
bool bColumnIndex = false;
eReader.GetData3DSizes(scanIndex, nRow, nColumn, nPointsSize, nGroupsSize, nCountsSize, bColumnIndex);
int64_t nSize = (nRow > 0) ? nRow : 1024; //Pick a size for buffers
double *xData = new double[nSize];
double *yData = new double[nSize];
double *zData = new double[nSize];
e57::CompressedVectorReader dataReader = eReader.SetUpData3DPointsData(
scanIndex, //!< scan data index
nSize, //!< size of each of the buffers given
xData, //!< pointer to a buffer with the x data
yData, //!< pointer to a buffer with the y data
zData); //!< pointer to a buffer with the z data
//still a size of 65536
dataReader.close();
delete xData;
delete yData;
delete zData;
}

Image::GetFrameCount sets Image::LastError to win32error c++ gdi+

This function changes active frame of image after some time
But when i try to get frame count of the dimension it sets image->lasterror to Win32Error
Is there is any way to fix it?
(Windows 10,Visual Studio 2017 community)
void PlayImageAnim(Gdiplus::Image*&image, int delay,bool Looped)
{
using namespace Gdiplus;
if (Looped == true)
{
while (true)
{
UINT dcount = 0;
GUID *dimensionsIDs;
dcount = image->GetFrameDimensionsCount();
dimensionsIDs = new GUID[dcount];
UINT frame_count = image->GetFrameCount(&dimensionsIDs[0]);
int y = 0;
GUID pageGUID = FrameDimensionTime;
int size = image->GetPropertyItemSize(PropertyTagFrameDelay);
Gdiplus::PropertyItem*pr_item = (Gdiplus::PropertyItem*)malloc(size);
for (UINT i = 0; i <= frame_count; i++)
{
/*graphics.DrawImage(image, image_rect);*/
/*long delay = ((long*)pr_item->value)[i] * 10;*/
image->SelectActiveFrame(&pageGUID, i);
std::this_thread::sleep_for(std::chrono::milliseconds(delay));
}
image->SelectActiveFrame(&pageGUID, 0);
}
}
else
{
UINT dcount = 0;
GUID *dimensionsIDs;
dcount = image->GetFrameDimensionsCount();
dimensionsIDs = new GUID[dcount];
UINT frame_count = image->GetFrameCount(&dimensionsIDs[0]);
GUID pageGUID = FrameDimensionTime;
int size = image->GetPropertyItemSize(PropertyTagFrameDelay);
Gdiplus::PropertyItem*pr_item = (Gdiplus::PropertyItem*)malloc(size);
for (UINT i = 0; i <= frame_count; i++)
{
image->SelectActiveFrame(&pageGUID, i);
std::this_thread::sleep_for(std::chrono::milliseconds(delay));
}
image->SelectActiveFrame(&pageGUID, 0);
}
}
it has to similar parts for other parts of project

WriteJPGBuffer method using libjpeg libraries instead of ijl15.lib

We have following method implemented using ijl15.lib API.
We want to use libjpeg libraries instead of ijl. How should I implement WriteJPGBuffer using libjpeg libraries? We are aware of LoadJPG and SaveJPG from file. However i want to write and read the jpg image in buffer using libjpeg libraries. Any inputs will be very helpul. Thank you in advance.
unsigned char WriteJPGBuffer(unsigned int &size)
{
size = 0;
int jErr;
JPEG_CORE_PROPERTIES jpgProps;
bool colorsSwapped;
if (!jpgSupported)
return NULL;
jErr = ijlInit(&jpgProps);
if (jErr != IJL_OK)
return NULL;
jpgProps.DIBWidth = m_width;
jpgProps.DIBHeight = -m_height;
jpgProps.DIBBytes = (unsigned char *)m_pData;
jpgProps.DIBPadBytes = 0 ;
jpgProps.DIBChannels = 4;
jpgProps.DIBColor = IJL_RGB;
jpgProps.JPGFile = NULL;
jpgProps.JPGWidth = m_width;
jpgProps.JPGHeight = m_height;
jpgProps.JPGChannels = 3;
jpgProps.JPGColor = IJL_YCBCR;
jpgProps.JPGSubsampling = IJL_411;
jpgProps.jquality = jpgQuality;
unsigned int iSize = m_width*m_height*3;
unsigned char * pBuffer = new unsigned char[iSize];
jpgProps.JPGSizeBytes = iSize;
jpgProps.JPGBytes = pBuffer;
jpgProps.jprops.jpeg_comment_size = (unsigned short)m_strCommentAdobe.length;
jpgProps.jprops.jpeg_comment = (char*)m_strCommentAdobe;
colorsSwapped = SetInternalFormat(RGB);
jErr = ijlWrite(&jpgProps, IJL_JBUFF_WRITEWHOLEIMAGE);
if (colorsSwapped)
SetInternalFormat(BGR);
if (jErr != IJL_OK)
{
ijlFree(&jpgProps);
return NULL;
}
size = jpgProps.JPGSizeBytes;
ijlFree(&jpgProps);
return jpgProps.JPGBytes;
}
Thanks for your inputs. I have implemented the solution below through RND. In below implementation, we have image data stored in the class member variable in the form of RGBQUAD which i am converting into unsigned char* first using ConversionfromGLRGBQUADToUnsignedChar function and then writing it jpeg buffer.
void ConversionfromGLRGBQUADToUnsignedChar(unsigned char* dataInCharFromGLRGBQUAD)
{
int spot,spotDst;
for (int y = 0;y < m_height;y++)
{
for (int x = 0;x<m_width;x++)
{
spot = y * m_width + x;
spotDst = spot * 3;
dataInCharFromGLRGBQUAD[spotDst] = m_pData[spot].red;
dataInCharFromGLRGBQUAD[spotDst + 1] = m_pData[spot].green;
dataInCharFromGLRGBQUAD[spotDst + 2] = m_pData[spot].blue;
}
}
}
unsigned char * WriteJPGBuffer(unsigned int &size)
{
size = 0;
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1];
unsigned char* dataInCharFromGLRGBQUAD;
bool colorsSwapped;
int row_stride;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
unsigned long sizeOfJPGBuffer = 0;
jpeg_mem_dest(&cinfo, &m_pDIBData, &sizeOfJPGBuffer);
cinfo.image_width = m_width;
cinfo.image_height = m_height;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
cinfo.jpeg_color_space = JCS_YCbCr;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, jpgQuality, true);
jpeg_start_compress(&cinfo, true);
colorsSwapped = SetInternalFormat(RGB);
FlipVert();
dataInCharFromGLRGBQUAD = new unsigned char[m_width*m_height*3];
ConversionfromGLRGBQUADToUnsignedChar(dataInCharFromGLRGBQUAD);
row_stride = cinfo.image_width * cinfo.input_components;
while (cinfo.next_scanline < cinfo.image_height)
{
row_pointer[0] = &dataInCharFromGLRGBQUAD[cinfo.next_scanline * row_stride];
jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
if (colorsSwapped)
SetInternalFormat(BGR);
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
size = sizeOfJPGBuffer;
delete[] dataInCharFromGLRGBQUAD;
return m_pDIBData;
}

C++ FMOD Studio can't give values to FMOD_DSP_PARAMETER_FFT for freq. analisys

I'm trying to represent the spectrum of a sound in a 3D plane but I only can play the sound and can't get the dsp into the structure FMOD_DSP_PARAMETER_FFT, numchannels and length are always = 0
My code is something like this:
FMOD::System *system;
FMOD::Sound *sound1;
FMOD::Channel *channel = 0;
FMOD::ChannelGroup *mastergroup;
FMOD::DSP *mydsp, *dsphead, *dspchannelmixer;
FMOD::DSPConnection *conection;
FMOD_RESULT result;
unsigned int version;
result = FMOD::System_Create(&system);
result = system->getVersion(&version);
result = system->init(32, FMOD_INIT_NORMAL, NULL);
result = system->createSound("mysong.mp3",FMOD_DEFAULT, 0, &sound1);
result = sound1->setMode(FMOD_LOOP_NORMAL);
result = system->playSound(sound1, 0, true, &channel);
/*
Create the DSP effect.
*/
result = system->createDSPByType(FMOD_DSP_TYPE_FFT, &mydsp);
result = mydsp->setParameterFloat(FMOD_DSP_FFT_SPECTRUMDATA, 300.0f);
result = system->getMasterChannelGroup(&mastergroup);
result = mastergroup->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &dsphead);
result = dsphead->getInput(0, &dspchannelmixer, 0);
result = dsphead->disconnectFrom(dspchannelmixer);
result = dsphead->addInput(mydsp, &conection);
result = mydsp->addInput(dspchannelmixer);
result = mydsp->setBypass(true);
result = mydsp->setActive(true);
char s[256];
unsigned int len;
float freq[32];
float fft = 0;
std::vector<float> fftheights;
//program loop
while (1) {
unsigned int ms = 0;
unsigned int lenms = 0;
bool playing = 0;
bool paused = 0;
int channelsplaying = 0;
if (channel)
{
FMOD::Sound *currentsound = 0;
result = channel->setPaused(false);
result = channel->setMute(false);
result = channel->isPlaying(&playing);
result = channel->getPaused(&paused);
result = channel->setVolume(0.5);
result = channel->getPosition(&ms, FMOD_TIMEUNIT_MS);
channel->getCurrentSound(&currentsound);
if (currentsound)
{
result = currentsound->getLength(&lenms, FMOD_TIMEUNIT_MS);
}
}
system->getChannelsPlaying(&channelsplaying);
render_function();
FMOD_DSP_PARAMETER_FFT *fftparameter;
result = mydsp->getParameterData(FMOD_DSP_FFT_SPECTRUMDATA, (void **)&fftparameter, 0, 0, 0);
result = mydsp->getOutput(FMOD_DSP_FFT_SPECTRUMDATA, &mydsp, 0);
for (int channelfft = 0; channelfft < fftparameter->numchannels; channelfft++)
{
for (int bin = 0; bin < fftparameter->length; bin++)
{
float val = fftparameter->spectrum[channelfft][bin];
if (channelfft == 0){
fftheights.push_back(val);
}
else{
fftheights[bin] += val;
}
}
}
result = system->update();
}
with this error I can't push back values into fftheights vector and always empty of 0, if you can help me I will agree.
Thank You.
I think you need to set those values using:
mydsp->setParameterInt( ... ); // <-- put stuff there
Also, check to see if the functions are returning any errors by looking at "result"
Look Here for more info.

C++: Convert float[] to unsigned char* or BYTE*

I'm developing a project where I need to convert PCM 16-bits 2 channels sound into a IEEE Float 32-bits 2 channels.
To do this I'm using the following code:
void CAudioConverter::ConvI16ToF32(BYTE* pcmFrom, BYTE* floatTo, int length)
{
short* src = reinterpret_cast<short*>(pcmFrom);
float* dst = reinterpret_cast<float*>(floatTo);
for (int n = 0; n < length; n++)
{
dst[n] = static_cast<float>(src[n]) / 32768.0f;
}
}
I have initialized the variable __pcm32_bytesPerFrame with:
WAVEFORMATEX* closestFormat;
ws->default_pb_dev->GetMixFormat(&closestFormat);
__pcm32_bytesPerFrame = closestFormat->nAvgBytesPerSec * (prm->samples_per_frame * 1000 / (prm->clock_rate * closestFormat->nChannels)) / 1000;
strm->pb_max_frame_count is:
hr = ws->default_pb_dev->GetBufferSize(&ws->pb_max_frame_count);
I have a while loop in a dedicated thread the does something like:
hr = strm->default_pb_dev->GetCurrentPadding(&padding);
incoming_frame = __pcm32_bytesPerFrame / 4;
frame_to_render = strm->pb_max_frame_count - padding;
if (frame_to_render >= incoming_frame)
{
frame_to_render = incoming_frame;
} else {
/* Don't get new frame because there's no space */
frame_to_render = 0;
}
if (frame_to_render > 0)
{
pjmedia_frame frame;
hr = strm->pb_client->GetBuffer(frame_to_render, &cur_pb_buf);
if (FAILED(hr)) {
continue;
}
void* destBuffer = (void*)malloc(strm->bytes_per_frame*frame_to_render*sizeof(pj_uint16_t));
if (strm->fmt_id == PJMEDIA_FORMAT_L16) {
/* PCM mode */
frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
frame.size = strm->bytes_per_frame;
frame.timestamp.u64 = strm->pb_timestamp.u64;
frame.bit_info = 0;
frame.buf = destBuffer;
}
status = (*strm->pb_cb)(strm->user_data, &frame);
CAudioConverter* conv = new CAudioConverter();
conv->ConvI16ToF32((BYTE*)destBuffer, cur_pb_buf, frame_to_render);
hr = strm->pb_client->ReleaseBuffer(frame_to_render, 0);
(...)
But, to send the sound to the WASAPI capture buffer I need a BYTE*.
How can I fill my 'floatTo' argument?
Any ideas?
Thanks
What about this:
void CAudioConverter::ConvI16ToF32(BYTE* pcmFrom, BYTE* floatTo, int length)
{
short* src = reinterpret_cast<short*>(pcmFrom);
float* dst = reinterpret_cast<float*>(floatTo);
for (int n = 0; n < length; n++)
{
dst[n] = static_cast<float>(src[n]) / 32768.0f;
}
}
Additionally make sure length indicates the number of elments in pcmFrom and floatTo, and not the number of bytes allocated. In you case pcmFrom should have allocated length*2 bytes and floatTo needs room for length*4 bytes.