В настоящее время я пытаюсь написать программу C ++, которая будет использоваться в качестве .dll с кодом Unity C#. До сих пор я успешно смог получить Unity передавать данные в .dll и наоборот. Тем не менее, я все еще довольно новичок в C ++ и наткнулся на все, и недавно стал проблемой, которую я не могу решить. Это стало немного сложнее из -за того, что я еще не понял отличное решение отладки. virtual float* GetNextSample(double timeAdvance) override{
currentSamplePosition = std::floor(currentPosition);
float centerSample = sampleData.waveform[currentSamplePosition];
for (int i = 0; i < channels; i++) {
currentSample = centerSample;
}
currentPosition += sampleData.positionRate * (frequency / sampleData.rootFrequency);
while (currentPosition >= sampleData.loopEnd) {
currentPosition -= (sampleData.loopEnd - sampleData.loopStart);
}
return currentSample;
}`
Общая проблема, по -видимому, заключается в том, что CurrentPostion не продвигается, таким образом, то Currentsample [] просто заполняется любыми данными на smpledata.waveform [0] .
Я отладко откладывал, изменяя линейные токи. и регистрация этих значений в редакторе Unity, так как Currentsample [] возвращается обратно в Unity и используется для заполнения аудио буфера. Например, для определения значений частоты и smpledata.rootfrequency , я устанавливаю токи выборки к этим значениям.
Таким образом, с указанным, я имею подтверждение, что частота = 440 и smpledata.rootfrecrentency = ~ 329.63. Эти переменные являются поплавками. Тем не менее, я обнаружил, что отладки, так это то, что если я устанавливаю образец Currents = (частота / sampledata.rootfrequency); < / code> или даже токи выборки = (static_cast (частота) / static_cast (sampledata.rootfrequence)); < / code>, возвращаемое в UNITY All All. Это разделение должно привести к приблизительно 1,3348, а не к нулю! Поскольку я подтвердил, что две переменные установлены должным образом, что они являются поплавками, и что другие значения возвращаются в единство, как и ожидалось, я понятия не имею, в чем еще проблема может быть на этом этапе. У кого -нибудь есть какие -либо советы?#define no_init_all deprecated
#include "pch.h"
#include "MoiseSynth_SamplePlayer.h"
#include "MoiseLibrary.h"
#include
float MoiseSynth::stepHz = _CMATH_::pow(2.0, 1.0 / 12.0);
MoiseSynth* testSynth;
double currentTime;
double timeAdvance;
int sampleRate;
void Init(int setSampleRate) {
sampleRate = setSampleRate;
timeAdvance = 1.0 / sampleRate;
currentTime = 0;
//testSynth->Initialize(sampleRate, 2);
}
float LoadSamplePlayerSynth(MOISE_SamplePlayer_Sample* data, int waveformSampleCount) {
testSynth = new MoiseSynth_SamplePlayer(data, waveformSampleCount);
testSynth->Initialize(sampleRate, 2);
return testSynth->GetWaveformValue(16);
}
void FillWaveformData(float data[], int sampleTotal, int channels) {
for (int i = 0; i < sampleTotal; i += channels) {
float* newSample = testSynth->GetNextSample(timeAdvance);
for (int j = 0; j < channels; j++) {
data[i+j] = newSample[j];
}
currentTime += timeAdvance;
}
}
< /code>
moisesynth.h
#pragma once
#include
#ifndef MOISE_SYNTH_H
#define MOISE_SYNTH_H
class MoiseSynth {
static float stepHz;
protected:
double currentTime;
float currentSample[1];
float frequency = 440;
float pan = 0.5;
double currentPosition = 0;
float currentEnvelopePosition;
float currentEnvelopeValue;
int currentSamplePosition;
int currentValue;
int sampleRate;
int channels;
bool active;
bool initialized;
public:
MoiseSynth() {
}
void Initialize(int setSampleRate, int setChannels) {
sampleRate = setSampleRate;
channels = setChannels;
initialized = true;
}
virtual float GetWaveformValue(int sampleIndex) {
return -1;
}
virtual float* GetNextSample(double timeAdvance) {
//This base class just returns a sine wave at 440Hz.
for (int i = 0; i < channels; i++) {
currentSample = std::sin(2 * 3.14159265358979323846 * 440 * currentTime);
}
currentTime += timeAdvance;
return currentSample;
}
};
#endif // !MOISE_SYNTH_H
< /code>
moisesynth_sampleplayer.h
#pragma once
#include "MoiseSynth.h"
#ifndef MOISE_SYNTH_SAMPLEPLAYER_H
#define MOISE_SYNTH_SAMPLEPLAYER_H
struct MOISE_SamplePlayer_Sample {
float* waveform;
float rootFrequency;
float waveformRate;
float positionRate;
int loopStart;
int loopEnd;
//MOISE_Note minNote;
//MOISE_Note maxNote;
};
struct MOISE_SamplePlayer_SampleBank {
MOISE_SamplePlayer_Sample sample[1];
};
class MoiseSynth_SamplePlayer : public MoiseSynth {
private:
MOISE_SamplePlayer_Sample sampleData;
public:
int activeSampleId = 0; //The ID of the sample to use.
MoiseSynth_SamplePlayer(MOISE_SamplePlayer_Sample* data, int waveformSampleCount) {
sampleData = *data;
}
void Initialize(int setSampleRate, int setChannels) {
sampleRate = setSampleRate;
channels = setChannels;
initialized = true;
}
float GetWaveformValue(int sampleIndex) override{
return sampleData.waveform[sampleIndex];
}
virtual float* GetNextSample(double timeAdvance) override{
currentSamplePosition = std::floor(currentPosition);
float centerSample = sampleData.waveform[currentSamplePosition];
for (int i = 0; i < channels; i++) {
currentSample = centerSample;
}
currentPosition += sampleData.positionRate * (frequency / sampleData.rootFrequency);
while (currentPosition >= sampleData.loopEnd) {
currentPosition -= (sampleData.loopEnd - sampleData.loopStart);
}
return currentSample;
}
};
#endif // !MOISE_SYNTH_SAMPLEPLAYER_H
< /code>
moiselibrary.h
#pragma once
#ifdef DLLPROJECT_EXPORTS
# define EXPORT __declspec(dllexport)
#else
# define EXPORT __declspec(dllimport)
#endif
extern "C" EXPORT void Init(int setSampleRate);
extern "C" EXPORT void FillWaveformData(float data[], int sampleTotal, int channels);
extern "C" EXPORT float LoadSamplePlayerSynth(MOISE_SamplePlayer_Sample* data, int waveformSampleCount);
< /code>
pch.h
// pch.h: This is a precompiled header file.
// Files listed below are compiled only once, improving build performance for future builds.
// This also affects IntelliSense performance, including code completion and many code browsing features.
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
// Do not add files here that you will be updating frequently as this negates the performance advantage.
#ifndef PCH_H
#define PCH_H
// add headers that you want to pre-compile here
#include "framework.h"
#endif //PCH_H
< /code>
framework.h
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#include
< /code>
c# код, который взаимодействует с .dll, следующим образом:
moise_interface: < /p>
using UnityEngine;
using System.Runtime.InteropServices;
using System.Collections.Generic;
namespace MOISE
{
public class MOISE_Interface : MonoBehaviour
{
[DllImport("MOISE")]
public static extern void Init(int sampleRate);
[DllImport("MOISE")]
public static extern void FillWaveformData(float[] data, int sampleTotal, int channels);
[DllImport("MOISE")]
public static extern float LoadSamplePlayerSynth(ref MOISE_SamplePlayer_Sample data, int waveformCount);
private List handles = new List();
private float currentTime;
private int channels = 2;
private void Update()
{
}
public void Initialize(Track trackToLoad, int sampleRate, int channels)
{
Init(sampleRate);
this.channels = channels;
}
public void FillWaveformData(float[] data)
{
FillWaveformData(data, data.Length, channels);
}
public void LoadSamplePlayerSynth(MOISE_SamplePLayer_SampleObject sampleObject, List loadedWaveforms, int sampleRate)
{
MOISE_SamplePlayer_Sample sampleToLoad = sampleObject.sampleData;
loadedWaveforms.Add(new float[sampleObject.sampleClip.samples]);
sampleObject.sampleClip.GetData(loadedWaveforms[loadedWaveforms.Count - 1], 0);
handles.Add(GCHandle.Alloc(loadedWaveforms[loadedWaveforms.Count - 1], GCHandleType.Pinned));
sampleToLoad.waveformPointer = handles[handles.Count - 1].AddrOfPinnedObject();
sampleToLoad.waveformRate = (float)sampleObject.sampleClip.frequency;
sampleToLoad.positionRate = sampleObject.sampleClip.frequency / (float)sampleRate;
sampleToLoad.rootFrequency = sampleObject.sampleData.rootFrequency;
sampleToLoad.loopStart = sampleObject.sampleData.loopStart;
sampleToLoad.loopEnd = sampleObject.sampleData.loopEnd;
Debug.Log("sampleToLoad waveform.length = " + loadedWaveforms[loadedWaveforms.Count - 1].Length);
Debug.Log("Loaded sample synth waveform value at 16 = " + LoadSamplePlayerSynth(ref sampleToLoad, loadedWaveforms[loadedWaveforms.Count - 1].Length));
}
}
}
< /code>
moise_player: < /p>
using UnityEngine;
using System.Collections.Generic;
namespace MOISE
{
public class MOISE_Player : MonoBehaviour
{
[SerializeField]
private MOISE_Interface moiseInterface = null;
[SerializeField]
private AudioSource audioSource;
private AudioClip moiseStream;
public Track testTrack;
public MOISE_SamplePLayer_SampleObject testSampleObject;
private List loadedWaveforms = new List();
[SerializeField]
private int sampleRate = 44100, channels = 2;
private void Awake()
{
moiseInterface.Initialize(testTrack, sampleRate, channels);
moiseInterface.LoadSamplePlayerSynth(testSampleObject, loadedWaveforms, sampleRate);
moiseStream = AudioClip.Create("MOISE_Stream", sampleRate * channels, channels, sampleRate, true, OnAudioRead);
audioSource.clip = moiseStream;
}
private void Start()
{
audioSource.loop = true;
audioSource.Play();
}
void OnAudioRead(float[] data)
{ //We need to update the audio stream
moiseInterface.FillWaveformData(data);
Debug.Log("Data[16] = " + data[16]);
}
}
}
< /code>
moise_sampleplayer_sampleobject: < /p>
using UnityEngine;
namespace MOISE
{
[CreateAssetMenu(fileName = "MOISE_SamplePlayer_SampleData", menuName = "MOISE/Sample Player/MOISE_SamplePLayer_SampleObject")]
public class MOISE_SamplePLayer_SampleObject : ScriptableObject
{
public AudioClip sampleClip;
public MOISE_SamplePlayer_Sample sampleData;
}
}
< /code>
moise_sampleplayer_struct: < /p>
using UnityEngine;
using System.Runtime.InteropServices;
namespace MOISE
{
[StructLayout(LayoutKind.Sequential)]
[System.Serializable]
public struct MOISE_SamplePlayer_Sample
{
public System.IntPtr waveformPointer;
public float rootFrequency, waveformRate, positionRate;
public int loopStart, loopEnd;
//public MOISE_Note minNote;
//public MOISE_Note maxNote;
}
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... -i-cant-fi
Разделение двух переменных поплавок в C ++, кажется, возвращается ноль, и я не могу понять, почему ⇐ C#
Место общения программистов C#
1752524176
Anonymous
В настоящее время я пытаюсь написать программу C ++, которая будет использоваться в качестве .dll с кодом Unity C#. До сих пор я успешно смог получить Unity передавать данные в .dll и наоборот. Тем не менее, я все еще довольно новичок в C ++ и наткнулся на все, и недавно стал проблемой, которую я не могу решить. Это стало немного сложнее из -за того, что я еще не понял отличное решение отладки. virtual float* GetNextSample(double timeAdvance) override{
currentSamplePosition = std::floor(currentPosition);
float centerSample = sampleData.waveform[currentSamplePosition];
for (int i = 0; i < channels; i++) {
currentSample[i] = centerSample;
}
currentPosition += sampleData.positionRate * (frequency / sampleData.rootFrequency);
while (currentPosition >= sampleData.loopEnd) {
currentPosition -= (sampleData.loopEnd - sampleData.loopStart);
}
return currentSample;
}`
Общая проблема, по -видимому, заключается в том, что CurrentPostion не продвигается, таким образом, то Currentsample [] просто заполняется любыми данными на smpledata.waveform [0] .
Я отладко откладывал, изменяя линейные токи. и регистрация этих значений в редакторе Unity, так как Currentsample [] возвращается обратно в Unity и используется для заполнения аудио буфера. Например, для определения значений частоты и smpledata.rootfrequency , я устанавливаю токи выборки [i] к этим значениям.
Таким образом, с указанным, я имею подтверждение, что частота = 440 и smpledata.rootfrecrentency = ~ 329.63. Эти переменные являются поплавками. Тем не менее, я обнаружил, что отладки, так это то, что если я устанавливаю образец Currents [i] = (частота / sampledata.rootfrequency); < / code> или даже токи выборки [i] = (static_cast (частота) / static_cast (sampledata.rootfrequence)); < / code>, возвращаемое в UNITY All All. Это разделение должно привести к приблизительно 1,3348, а не к нулю! Поскольку я подтвердил, что две переменные установлены должным образом, что они являются поплавками, и что другие значения возвращаются в единство, как и ожидалось, я понятия не имею, в чем еще проблема может быть на этом этапе. У кого -нибудь есть какие -либо советы?#define no_init_all deprecated
#include "pch.h"
#include "MoiseSynth_SamplePlayer.h"
#include "MoiseLibrary.h"
#include
float MoiseSynth::stepHz = _CMATH_::pow(2.0, 1.0 / 12.0);
MoiseSynth* testSynth;
double currentTime;
double timeAdvance;
int sampleRate;
void Init(int setSampleRate) {
sampleRate = setSampleRate;
timeAdvance = 1.0 / sampleRate;
currentTime = 0;
//testSynth->Initialize(sampleRate, 2);
}
float LoadSamplePlayerSynth(MOISE_SamplePlayer_Sample* data, int waveformSampleCount) {
testSynth = new MoiseSynth_SamplePlayer(data, waveformSampleCount);
testSynth->Initialize(sampleRate, 2);
return testSynth->GetWaveformValue(16);
}
void FillWaveformData(float data[], int sampleTotal, int channels) {
for (int i = 0; i < sampleTotal; i += channels) {
float* newSample = testSynth->GetNextSample(timeAdvance);
for (int j = 0; j < channels; j++) {
data[i+j] = newSample[j];
}
currentTime += timeAdvance;
}
}
< /code>
moisesynth.h
#pragma once
#include
#ifndef MOISE_SYNTH_H
#define MOISE_SYNTH_H
class MoiseSynth {
static float stepHz;
protected:
double currentTime;
float currentSample[1];
float frequency = 440;
float pan = 0.5;
double currentPosition = 0;
float currentEnvelopePosition;
float currentEnvelopeValue;
int currentSamplePosition;
int currentValue;
int sampleRate;
int channels;
bool active;
bool initialized;
public:
MoiseSynth() {
}
void Initialize(int setSampleRate, int setChannels) {
sampleRate = setSampleRate;
channels = setChannels;
initialized = true;
}
virtual float GetWaveformValue(int sampleIndex) {
return -1;
}
virtual float* GetNextSample(double timeAdvance) {
//This base class just returns a sine wave at 440Hz.
for (int i = 0; i < channels; i++) {
currentSample[i] = std::sin(2 * 3.14159265358979323846 * 440 * currentTime);
}
currentTime += timeAdvance;
return currentSample;
}
};
#endif // !MOISE_SYNTH_H
< /code>
moisesynth_sampleplayer.h
#pragma once
#include "MoiseSynth.h"
#ifndef MOISE_SYNTH_SAMPLEPLAYER_H
#define MOISE_SYNTH_SAMPLEPLAYER_H
struct MOISE_SamplePlayer_Sample {
float* waveform;
float rootFrequency;
float waveformRate;
float positionRate;
int loopStart;
int loopEnd;
//MOISE_Note minNote;
//MOISE_Note maxNote;
};
struct MOISE_SamplePlayer_SampleBank {
MOISE_SamplePlayer_Sample sample[1];
};
class MoiseSynth_SamplePlayer : public MoiseSynth {
private:
MOISE_SamplePlayer_Sample sampleData;
public:
int activeSampleId = 0; //The ID of the sample to use.
MoiseSynth_SamplePlayer(MOISE_SamplePlayer_Sample* data, int waveformSampleCount) {
sampleData = *data;
}
void Initialize(int setSampleRate, int setChannels) {
sampleRate = setSampleRate;
channels = setChannels;
initialized = true;
}
float GetWaveformValue(int sampleIndex) override{
return sampleData.waveform[sampleIndex];
}
virtual float* GetNextSample(double timeAdvance) override{
currentSamplePosition = std::floor(currentPosition);
float centerSample = sampleData.waveform[currentSamplePosition];
for (int i = 0; i < channels; i++) {
currentSample[i] = centerSample;
}
currentPosition += sampleData.positionRate * (frequency / sampleData.rootFrequency);
while (currentPosition >= sampleData.loopEnd) {
currentPosition -= (sampleData.loopEnd - sampleData.loopStart);
}
return currentSample;
}
};
#endif // !MOISE_SYNTH_SAMPLEPLAYER_H
< /code>
moiselibrary.h
#pragma once
#ifdef DLLPROJECT_EXPORTS
# define EXPORT __declspec(dllexport)
#else
# define EXPORT __declspec(dllimport)
#endif
extern "C" EXPORT void Init(int setSampleRate);
extern "C" EXPORT void FillWaveformData(float data[], int sampleTotal, int channels);
extern "C" EXPORT float LoadSamplePlayerSynth(MOISE_SamplePlayer_Sample* data, int waveformSampleCount);
< /code>
pch.h
// pch.h: This is a precompiled header file.
// Files listed below are compiled only once, improving build performance for future builds.
// This also affects IntelliSense performance, including code completion and many code browsing features.
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
// Do not add files here that you will be updating frequently as this negates the performance advantage.
#ifndef PCH_H
#define PCH_H
// add headers that you want to pre-compile here
#include "framework.h"
#endif //PCH_H
< /code>
framework.h
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#include
< /code>
c# код, который взаимодействует с .dll, следующим образом:
moise_interface: < /p>
using UnityEngine;
using System.Runtime.InteropServices;
using System.Collections.Generic;
namespace MOISE
{
public class MOISE_Interface : MonoBehaviour
{
[DllImport("MOISE")]
public static extern void Init(int sampleRate);
[DllImport("MOISE")]
public static extern void FillWaveformData(float[] data, int sampleTotal, int channels);
[DllImport("MOISE")]
public static extern float LoadSamplePlayerSynth(ref MOISE_SamplePlayer_Sample data, int waveformCount);
private List handles = new List();
private float currentTime;
private int channels = 2;
private void Update()
{
}
public void Initialize(Track trackToLoad, int sampleRate, int channels)
{
Init(sampleRate);
this.channels = channels;
}
public void FillWaveformData(float[] data)
{
FillWaveformData(data, data.Length, channels);
}
public void LoadSamplePlayerSynth(MOISE_SamplePLayer_SampleObject sampleObject, List loadedWaveforms, int sampleRate)
{
MOISE_SamplePlayer_Sample sampleToLoad = sampleObject.sampleData;
loadedWaveforms.Add(new float[sampleObject.sampleClip.samples]);
sampleObject.sampleClip.GetData(loadedWaveforms[loadedWaveforms.Count - 1], 0);
handles.Add(GCHandle.Alloc(loadedWaveforms[loadedWaveforms.Count - 1], GCHandleType.Pinned));
sampleToLoad.waveformPointer = handles[handles.Count - 1].AddrOfPinnedObject();
sampleToLoad.waveformRate = (float)sampleObject.sampleClip.frequency;
sampleToLoad.positionRate = sampleObject.sampleClip.frequency / (float)sampleRate;
sampleToLoad.rootFrequency = sampleObject.sampleData.rootFrequency;
sampleToLoad.loopStart = sampleObject.sampleData.loopStart;
sampleToLoad.loopEnd = sampleObject.sampleData.loopEnd;
Debug.Log("sampleToLoad waveform.length = " + loadedWaveforms[loadedWaveforms.Count - 1].Length);
Debug.Log("Loaded sample synth waveform value at 16 = " + LoadSamplePlayerSynth(ref sampleToLoad, loadedWaveforms[loadedWaveforms.Count - 1].Length));
}
}
}
< /code>
moise_player: < /p>
using UnityEngine;
using System.Collections.Generic;
namespace MOISE
{
public class MOISE_Player : MonoBehaviour
{
[SerializeField]
private MOISE_Interface moiseInterface = null;
[SerializeField]
private AudioSource audioSource;
private AudioClip moiseStream;
public Track testTrack;
public MOISE_SamplePLayer_SampleObject testSampleObject;
private List loadedWaveforms = new List();
[SerializeField]
private int sampleRate = 44100, channels = 2;
private void Awake()
{
moiseInterface.Initialize(testTrack, sampleRate, channels);
moiseInterface.LoadSamplePlayerSynth(testSampleObject, loadedWaveforms, sampleRate);
moiseStream = AudioClip.Create("MOISE_Stream", sampleRate * channels, channels, sampleRate, true, OnAudioRead);
audioSource.clip = moiseStream;
}
private void Start()
{
audioSource.loop = true;
audioSource.Play();
}
void OnAudioRead(float[] data)
{ //We need to update the audio stream
moiseInterface.FillWaveformData(data);
Debug.Log("Data[16] = " + data[16]);
}
}
}
< /code>
moise_sampleplayer_sampleobject: < /p>
using UnityEngine;
namespace MOISE
{
[CreateAssetMenu(fileName = "MOISE_SamplePlayer_SampleData", menuName = "MOISE/Sample Player/MOISE_SamplePLayer_SampleObject")]
public class MOISE_SamplePLayer_SampleObject : ScriptableObject
{
public AudioClip sampleClip;
public MOISE_SamplePlayer_Sample sampleData;
}
}
< /code>
moise_sampleplayer_struct: < /p>
using UnityEngine;
using System.Runtime.InteropServices;
namespace MOISE
{
[StructLayout(LayoutKind.Sequential)]
[System.Serializable]
public struct MOISE_SamplePlayer_Sample
{
public System.IntPtr waveformPointer;
public float rootFrequency, waveformRate, positionRate;
public int loopStart, loopEnd;
//public MOISE_Note minNote;
//public MOISE_Note maxNote;
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79701280/division-of-two-float-variables-in-c-seems-to-be-returning-zero-and-i-cant-fi[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия