Wave Source Component -- Proof of Concept Code

This is a first pass at a component to read *.wav files. Works but not yet perfect.

The forum doesn’t allow attaching *.cpp and *.h (and *.qsch) files. So I appended “.txt” to the file names to work around this limitation.

This doesn’t work for *.qsch presumably due to some non-plaintext characters in the *.qsch file. The component/schematic is pretty simple to create – just a single output port named Out of type float (64-bit double). Looks like this:

Sample output from 1KHz sine sample file (which I also cannot upload).

Please let me know if you try it, have questions or improvements/corrections.
wavsrc.cpp.txt (14.1 KB)
WavSrc.h.txt (1.7 KB)

– robert

3 Likes

Hi, robert
I tried it and it works fine. Great job!
image


wave data = sin 1kHz + sin 1.1kHz

I just added the ability to pass a string to a .DLL device. So you can pass a path to a .DLL, have it read the .wav file, and then play it into the simulation.

–Mike

Thanks, Mike! I’ll update/check it out immediately.

–robert

@Engelhardt

OK, uninstalled/reinstalled QSpice with reboots (just to reset things), downloaded and installed.

Generated a new component with an added attribute, “FileName”. Looks like this:
image

Tried that with & without quotes on the parameter.

Has the code generator been updated to generate string parms? All I see in the generated code is:
double &Out = data[0].d; // output

I expected another index, something like:
const char* Attr1 = data[1],str;

The netlist does contain the parameter (one of several variations):

      * C:\Dev\QSpice\Projects\WavSrc2\WavSrc.qsch
      ؆X1 «» «Vout´d» «»  WavSrc FileName="ABC"
      R1 Vout 0 1Meg
      .tran 150ms
      .end

I’ll mess around – it should be there as the next parameter. But let me know if I’m obviously on the wrong track.

Thanks!
–robert

Instead of

FileName=“ABC”

use

char *filename=“abc”

not that case makes a difference.

For more options passing parameters to the .DLL, point at symbol and press “F1”

–Mike

@Engelhardt

Well, I thought that I tried that yesterday. Anyway, updated QSpice and it works today. Excellent.

I was going to mention making it const but I see that you’re way ahead of me.

Thanks.

–robert

@Engelhardt

OK, I decided to add a second attribute. The auto-generate doesn’t include the additional value in the code. It is present in the netlist.

FWIW, I also tried bool loop=false & bool loop=0. Those also didn’t get included in the code although present in the netlist. Also tried exiting/restarting QSpice. No joy.

Thanks.

–robert

Oh, it was only working if the char * parameter was the last attribute. But I changed it as of the current update so that you can put “int loop=1 bool done=false” after the char * parameter.

But you will have to regenerate the C++ template with the right click C++ => Create C++ Template command.

–Mike

@Engelhardt

Thanks. Working on the project now so I’ll update and see how it goes.

–robert

@Engelhardt

Looks like the code generation issue is fixed. Will roll it into my code and let you know if there are more problems. I don’t expect any.

While it’s not your issue to solve or a proper topic for this thread, the QSpice update process is horribly broken. I’ll post about that separately. Just had to vent.

Thanks for all of your prompt help!

–robert

OK, I think that I have the WavSrc component functionally complete. Here’s what it does:

  • Reads a *.wav file with single or dual channels. Currently only basic 16-bit PCM-encoded files are supported. (Probably won’t add more formats.) If only one channel is present, it simply duplicates the data on the second output.

  • File is specified with an attribute. Seems to honor path bits properly.

  • Has a gain attribute to apply to the nominal 1.0Vp input values.

  • Has a Vref input which is sets the 0V reference. It could be a DC offset or , in theory, be used to modulate the wav outputs.

  • Has a loops attribute to specify how many times the input file is read/processed,

Here’s a sample setup:

V1 is for comparison against a sample wav file:
image

And zoomed:

WavSrc CH1 tracks Vsin quite nicely with, of course, digital sample stepping.

Need to do a bit more cleanup before sharing but that’s the preview.

If anyone thinks of something else to add, please let me know.

–robert

6 Likes

Hi,

Thank you for this POC component!

I’m running into a strange issue. I generated a very simple .wav file. (1KHz for 100ms at 1Vpp).
However, if a place a 1 ohm resistor to GND on the output, the output Voltage is 1mVpp.
If I change the resistor to GND to 1Gohms. I get the 1Vpp of the .wav file.
I’m getting use to the C++ interface and your original .cpp code. However, I hadn’t detected the effect of a series resistance in your code.

Len

UPDATE!!!

I just found the ROUT=1000 ohm default output setting in the Symbol Text help info. Once I change ROUT = 1f, I get my expected 1Vpp results.

Robert,

Do you have updated .cpp file to achieve the extra input parameters such is filenames, loop, etc?

Len

@lpoma

I do but haven’t posted it yet. Probably later today.

–robert

OK, here are the current Proof of Concept WAV code and sample files: GitHub - robdunn4/QSpice-WavSrc: QSpice schematics, symbols, code, tools, etc.. There’s no “user documentation” yet – just the C-Block code and schematic and some test WAV files.

Note that, after I learn a bit more about GitHub, I’ll likely move the project to a different repository with better organization. In other words, the link won’t likely be active forever…

Let me know what works, doesn’t work, etc. TIA.

Edit: I’m struggling with trying to get the code rolled into a symbol. Seems like it should be simple but passing in parameters (i.e., filename, loops, gain) from the symbol dropped into a schematic to the underlying stuff is eluding me. Feel free to beat me to that, share, and be my hero.

–robert

Are you planning to create the compliment feature, outputting a WAV file from a QSPICE signal? I used that feature in LTspice to simulate the stereo output of the ShortSniffer during the development phase. The hardware prototype performed in a similar fashion, sounding just like the simulation!

I’ve thought about it but no current plans. The basic structure of the code could be adapted to write instead of read… Care to give it a try?

–robert

I looked at the C++ code and realized that I’m not the guy to do the job. I’m an Analog Guy with minimal code hacking abilities (BASIC and assembly from TRS-80 and early PCs). Maybe somebody else will get excited about the challenge . . .
Thanks for what you are doing.
Carl

1 Like

Hi, Carlvanwormer. See WavIO Components for QSpice (*.wav files) for new code.

–robert