Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[request] import sound tool/cmd (wave data not tracker) #2162

Open
atesin opened this issue Apr 6, 2023 · 63 comments
Open

[request] import sound tool/cmd (wave data not tracker) #2162

atesin opened this issue Apr 6, 2023 · 63 comments

Comments

@atesin
Copy link

atesin commented Apr 6, 2023

hi... the documentation is very swallow... but i was reading the "import" console command, not too much explanatory

as far as i understood, we can open tic-80 folder ("folder" command) and once opened we can place any file we want, for each tic80 "editor":

  • code = txt file?
  • sprites = png/bmp files?
  • map = no idea which filetype, xls?
  • tracker = midi files?, mod/xm?

but what about SOUND? ... is very tedious having to plot waves dot by dot, moreover i cant imagine how it will end sounding, is more like a trial-error process... it is also very hard to try to match some sound with other "real" one, would be great if we could just sample, lower the quality and just import

would be great if import could also work with sound files (wav?), and the documentation specifies the process and wave format (frequency, bit resolution, which voice/channel, etc)

.... in case it doesnt support.. if does could you please update documentation in details?... thanks

@joshgoebel
Copy link
Collaborator

joshgoebel commented Apr 6, 2023

You don't really have much storage for something like a WAV file...

https://github.com/nesbox/TIC-80/wiki/RAM#sound-registers

You can update the Sound Registers every tick (60 times per second) to generate sound independently from the built-in API functions.

So with custom programming you could have 1.92khz (60*32), 4 bit audio... at the cost of like 1kb of storage per second... perhaps enough for like a few very specific and distorted sound effects...? Or if you gave up MAP you could store 32 seconds of audio or so... maybe like if you had an audio "cut scene" paired with a graphic? But you'll burn thru that storage fast...

@atesin
Copy link
Author

atesin commented Apr 6, 2023

i dont know tic80 internals, but i doubt it stores raw wave data in memory, like you i think it would consume a lot of memory.... but i think instead, it stores some points needed to "draw" the wave, and those are the dots you see when you "draw" the wave in sfx editor and tic80 read and interprets when sounds are played

i would like to know if could be have ANY way of import some sound inside tic80, not only by store wav data directly but also could be a reader/analyzer that parses a .wav file and tell tic80 what points to plot in sfx editor...

a sound copy/paste function would be terrific, or a wav file importer/analyzer command or external tool would be great also... it would greatly improve que quality of our sfxs/songs

@joshgoebel
Copy link
Collaborator

but i doubt it stores raw wave data in memory,

Well, it doesn't really store "raw wav data" at all - or rather it has no where specific to store such data... you could encode it into your program source, or store it in your cartridge... but to play it you have to use the facilities that TIC-80 gives you sound wise - which [most directly] are the sound registers... 32 samples of 4-bit audio that you'd have to make last 1/60 of a second... you'd have to constantly fill each frame from whereever you had the WAV data stored.

i would like to know if could be have ANY way of import some sound inside tic80,

Sure. Just downsample to 1.92kb 4-bit audio, store it in the cartridge RAM, and then write a program to read it and shove it into the sound register every frame. It would be a pretty cool demo actually.

My worry would be timing issues, that TIC-80 isn't really designed/tested to work this way and you might do all that work just to find out you have clicks or dropped audio or other strange issues... but maybe it "just works"...

@joshgoebel
Copy link
Collaborator

I think something like https://sox.sourceforge.net/sox.html could get you close to the raw data you'd need... output a mono 4-bit 1.92khz raw file... the you'd just need a small script to convert that raw file into textual binary data (the same way TIC-80 saves such data in text mode)... then you just need to write the audio processing code. :-)

@joshgoebel
Copy link
Collaborator

joshgoebel commented Apr 7, 2023

sox input.mp3 -b8 -c1 -r1920 -eunsigned-integer out.raw

Doesn't seem to want to write 4-bit so you'd have to also convert the 8-bit samples to 4-bit, easy enough. Doesn't sound great already though, you'd probably want to specially process the audio for such tight encoding, not just convert it "as is".

Ok, sox is amazing and if you knew what you needed it could probably do any type of post-processing you needed to try and clean the audio up...

@joshgoebel
Copy link
Collaborator

joshgoebel commented Apr 7, 2023

a wav file importer/analyzer command

This is unlikely since there is really no way to use that data without a lot of custom programming. Importing a MIDI would honestly make way more sense, etc... https://github.com/wojciech-graj/TIC-MIDI

@atesin
Copy link
Author

atesin commented Apr 7, 2023

i agree with you about midi... but midi are just song patterns without any actual sound wave

for example to make music, i have no idea how to create bassdrum kick or claps or cymbal sounds, or how "looks" a violin or trumpet or any other "real world" sound... i can't imagine how sounds are "seen" graphically to replicate it :(

i would like if we could sample some sounds in some ecternal editor tool like audacity, audition, soundforge, etc... process it, stretch to required freq/lenght, downsampling, export to wav.... then run a tool to read wav files, parses and put data in a .cart directly

that wav file parser+importer would be a very powerful and useful tool, we could just use all the power of some external sound editor, we could put very rich sounds inside tic80

@atesin atesin changed the title [request] import sound (wave data not tracker) [request] import sound tool/cmd (wave data not tracker) Apr 7, 2023
@bztsrc
Copy link
Contributor

bztsrc commented Apr 7, 2023

hi... the documentation is very swallow...

I agree!

Well, it doesn't really store "raw wav data" at all

I'm fairly certain that it does, at offset 0xFFE4 (see wiki). It's just not the entire song is stores as wave, only the instruments (which then is put together into a whole song using the tracker).

but midi are just song patterns without any actual sound wave

That's for the tracker. The tracker contains song patterns, not waves either.

for example to make music, i have no idea how to create bassdrum kick or claps or cymbal sounds, or how "looks" a violin or trumpet or any other "real world" sound... i can't imagine how sounds are "seen" graphically to replicate it :(

If you're familiar with old-school trackers (FT2, OpenMPT, MilkyTracker etc.), then those work similarly like TIC-80: they have a few instruments, stored as waves, and MIDI-like patterns with musical notes. You can load a .mod file with a trumpet or violin for example and see the waveform in those trackers. However .mod files have 8-bit or 16-bit samples, and one instrument might have up to 65536 samples. On TIC-80, one sample is stored on 4-bit, and you have only 32 samples, but despite the limited precision the wave must look the same to give the same sound.

Another approach try using Audacity. Load a violin wave for example which is 1 second long, then on the bottom left enter "32 Hz" (this only works if the length of the sample is 1 sec). The resulting waveform should then look like exactly like the one you have to set in TIC-80 for a similar sound.

I'd like to point out that violin has probably one of the most complex waveform with lots of harmonics. It is highly unlikely that you'll be able to reproduce it using chip-tunes. But at least, using the methods above, you'll see how the sound's wave should look like.

Hope this helps,
bzt

@bztsrc
Copy link
Contributor

bztsrc commented Apr 7, 2023

run a tool to read wav files, parses and put data in a .cart directly

Ah, about that, it won't work. You might be able to use wav files for the waveforms only, and not for the entire song as stored in the .cart.

(Maybe if the song is simple, then you can locate the individual instrument wave in that, and using sophisticated 1-d pattern matching algorithms or maybe AI you can convert that into a list of musical notes required for the tracker. But it is highly unlikely that you can do this with complex songs where multiple instruments are played at once, specially when the same instrument playing multiple notes at the same time.)

Here's a good explanation why is it impossible what you ask (talks about MIDI, but the same stands for any tracker, TIC-80 patterns included).

Cheers,
bzt

@atesin
Copy link
Author

atesin commented Apr 7, 2023

If you're familiar with old-school trackers (FT2, OpenMPT, MilkyTracker etc.), then those work similarly like TIC-80

yes, but they do read and import .wav files as instruments, while tic80 dont

Another approach try using Audacity. Load a violin wave for example which is 1 second long, then on the bottom left enter "32 Hz" (this only works if the length of the sample is 1 sec). The resulting waveform should then look like exactly like the one you have to set in TIC-80 for a similar sound.

NICE HINT!

run a tool to read wav files, parses and put data in a .cart directly

Ah, about that, it won't work. You might be able to use wav files for the waveforms only, and not for the entire song as stored in the .cart.

hi.... i never talked about importing an entire .wav song inside a cart, that is unlikely... but about putting sound samples in sfx editor wave slots instead

i would like a tool to get some .wav SAMPLES of about 1 second, fixed frequency, etc.. and make it appear inside tic80 sfx editor wave slots (obviously with lower quality)..... that way we can get some samples from outside and make nice songs or sfx's in tic80

@bztsrc
Copy link
Contributor

bztsrc commented Apr 7, 2023

about putting sound samples in sfx editor wave slots instead

TBH I got so frustrated not getting answers to my TIC-80 audio questions for months that I wrote my own fantasy console in the meantime... It can import / export Amiga MOD (.mod) tracker files and General MIDI (.mid) music sheets too (for the latter there are some built-in wave samples or you can import .wav files directly). To see it in action click here (just drag'n'drop the "demo floppy" to the floppy drive, and the music will start).

i would like a tool to get some .wav SAMPLES of about 1 second, fixed frequency, etc..

The soundbank for the built-in waves for my fantasy console is here. It is in Amiga MOD format, but all you need is the samples in that file. Has 2 instruments per General MIDI family, each approx. 1 sec long, max 16k samples, all tuned to C-4 (except the violin, that's tuned to G-4). It is exactly what you asked for, but you'll need some work to scale these down to TIC-80 waves.

Oh, one more thing, these samples are licensed under GPL.

Hope this helps,
bzt

@joshgoebel
Copy link
Collaborator

I'm fairly certain that it does, at offset 0xFFE4 (see wiki).

Yes, if we're being quite technical... :-) but that (at a very slow cadence) is only 1/60 a second of wave data... there is no where clear to just import a 20 second (or even 1 second) wav data - which is what this user is requesting when they say "wav data"... they mean a few seconds (at least), not a 1/60s waveform.

i would like a tool to get some .wav SAMPLES of about 1 second

The TIC-80 "samples" (waveforms) are 1/60 a second. So a full second would require 60 samples, but we have only 16. So you're back to trying to copy things in and out of the audio registers if you want like 1 second samples.

You might first try downsampling your content to 2.1khz and see if you're even happy with the result... it sounds pretty awful. (I tried a whole song)

@atesin
Copy link
Author

atesin commented Apr 7, 2023

@joshgoebel : see the 16 waveform slots at sfx editor?

image

well... i wish some tool to import external waveforms to THAT slots, whatever the duration or quality they have ..... i never had talked about a 20secs song or whatever... you are making too many wrong asumptions about i said

if waveforms at sfx editor stores 1/60 second, then the .wav samples to import should have 1/60 second.... no problem


i hope i had talked clearly enough... i am thinking in something like, for example:

  • process a dog barking sound in audacity or other software... with fixed frequency, duration, etc
  • save as wave, doesnt matter if too short or low quality
  • execute some tic80 command or external tool like ...
> import sfx woof.wav id=11
  • then... it appears in bank 11 waveform, avaliable for our game or app like some 'dog game' or song

image

  • additionally, you could later import a midi pattern to make a song using this new sfx... but that is outside the scope of this request

@joshgoebel
Copy link
Collaborator

I think you're not imagining how short 1/60 of a second is... 🙀 you couldn't put "woof" in there, but perhaps just part of a very rough w or o sound...

And I think my suggestion of sox is about as close as you're going to get...

  • sox gets you the raw data in 8-bit binary form (ie wav or mp3 => raw 8-bit)
  • read new file one byte at a time, downsample to 4-bit (shift right)
  • output ASCII ready to cut and paste into cartridge external editor

ChatGPT could probably even help you with those last two. :)

@joshgoebel
Copy link
Collaborator

Screen Shot 2023-04-07 at 5 43 15 PM

@joshgoebel
Copy link
Collaborator

Oops, forgot the 4-bit encoding:

file = File.open("binary_file", "rb") # open the binary file in read-binary mode
bytes = file.read.bytes # read the bytes from the file
if bytes.length.odd? # pad the last byte with zeros if there are an odd number of bytes
  bytes.push(0)
end
output_bytes = bytes.each_slice(2).map do |slice| # group the input bytes into pairs and process them
  (slice[0] & 0xF0) | ((slice[1] >> 4) & 0x0F) # squeeze the pair of bytes into a single byte
end
hex_chars = output_bytes.map { |b| "%02X" % b }.join(" ") # convert the output bytes to hex-encoded characters
puts hex_chars # print the resulting hex-encoded string

@joshgoebel
Copy link
Collaborator

joshgoebel commented Apr 7, 2023

If someone can come up with a sox conversion of a popular mp3 that doesn't sound like garbage (ie the correct post-processing to clean up the audio for such tiny-ness) I might be persuaded to write the inside TIC-80 code needed for play the audio stream using the audio registers... and show how such a thing should be done... I was using "build me up buttercup" and it was pretty bad even in 8-bit, 2.1khz...

@bztsrc
Copy link
Contributor

bztsrc commented Apr 7, 2023

sox gets you the raw data in 8-bit binary form (ie wav or mp3 => raw 8-bit)

Wav is also just raw binary data, just with a little header (here is a description). I think .wav is a much better choice because it's more widespread than sox.

If someone can come up with a sox conversion of a popular mp3 that doesn't sound like garbage

That's quite a challenge. I think it would be better imho just let third party tools do the conversion (like Audacity), and only provide loading in TIC-80. Much simpler and easier to implement (all you have to do is then downscaling 8-bit or 16-bit samples to 4-bit, which is essentially is simple as taking the most significant 4-bits and that's it.)

import sfx woof.wav id=11

I like this version, clear and straightforward. But @joshgoebel is right, the wav file should have only 32 samples for this to work, which isn't much. (But at least this command would allow importing properly prepared waveforms from third party software like Audacity.)

Cheers,
bzt

@joshgoebel
Copy link
Collaborator

I think .wav is a much better choice

Apples and oranges. sox is a popular audio command line utility (link earlier in thread)... it can take tons of different audio files and provide simple raw output.

I think it would be better imho just let third party tools

Yes... sox is such a tool... but it has 100 options for low pass filters, gain, volume, etc... surely some of them can improve the quality of low bit rate audio, for example I had some luck with normalizing and turning up the gain...

I'm still curious about writing a test cart to play a whole song... and see how well that might (or might not) work... I think with the right music choice it might be useful for like 30s graphical cut-scenes in a game with audio (not chiptunes).

@atesin
Copy link
Author

atesin commented Apr 8, 2023

I think you're not imagining how short 1/60 of a second is...

you are making too many wrong asumptions about i said

yes of course i know.... is a single cycle at 60hz, or 2 at 120hz, 3 at 180hz... or 10 at 600 hz, etc ...about 17ms, like the duration of a clap, but enough for the human ear to distinguish a clap from a hit or a crash or a blow or other short sound.... anyway, tic80 plays the samples in loop so the sound is perceived longer and more distinguishable

additionally.. if you process a bark sound externally, downsample and cut at 17ms then import into tic80 soundwave bank someway... then in tic80 you can process it with ENVELOPES (and tracker commands if composing a song)... chances are you could achieve a distorted but very recognizable "woof" sound

envelopes:
image

please dont expand this conversation furthermore in soundwaves duration, and focus in how to achieve the requested


with a tool like this, we could even sample some human voices and import them into tic80... then create some instruments using this wave, with different envelopes, to simulate NPC characters speaking in an RPG game ... speaking nonsensical words of course, but through this we could give them some sort of "personality", like in hollow knight

a tool like this will open many posibilities

@joshgoebel
Copy link
Collaborator

joshgoebel commented Apr 8, 2023

I've given you all the pieces you need to import the audio data.

  • run your (very small) wav file thru sox to get a 8-bit raw data file (sox input.wav -b8 -c1 -r1920 -eunsigned-integer output.raw)
  • run that thru the Ruby script to get the 4-bit encoded data TIC-80 wants
  • copy that into a textual TIC-80 cart into it's WAVEFORM section (new lua; save cart.lua, etc)

I have no suggestions for playing with the right side of the audio stuff...

@joshgoebel
Copy link
Collaborator

joshgoebel commented Apr 8, 2023

we could even sample some human voices and import them into tic80.

You could, but human vocals really require higher frequencies than TIC-80 supports... ideally 8-16khz... which I assume is why I've been struggling to get good results at only 2khz.

There is some question about whether maybe you could string multiple 'sfx' together though - and if the sound 'hardware' would give you better output than you can get driving it by hand... for example if you could load ALL 16 WAVEFORMS with sequential audio data... then play a "melody" very fast that is just WAVE 1, WAVE 2, WAVE 3, WAVE 4, etc... (with the timing end perfectly on the 1/60 boundary)... then you'd have 32khz audio.

Of course you'd never want to sample that highly (RAM)... but that's just the "how" you might go about it... in my testing even 4khz was like 10x better sounding audio than 2khz. And that would only require 2 back to back waveforms/sfx.

@atesin
Copy link
Author

atesin commented Apr 8, 2023

but human vocals really require higher frequencies than TIC-80 supports... ideally 8-16khz... which I assume is why I've been struggling to get good results at only 2khz

chances are you could achieve a distorted but very recognizable "woof" sound

i say "distorted" .... i know...... anyway if somebody feels creative and need a little more quality, he/she could sample the sound at lower freq and play at higher one.. for human voice is ok because is very unlikely somebody normally speak at 5th octave

please stop of misinterpreting me and putting me obstacles.... i feel like it i would like to run and you are putting me stones in my path..... focus

i am not a programmer.. that is because the "[request]" label on the issue title ... i hope somebody with the needed skill and experience will feel motivated and write a tool like this ... or if the official tic80 team add this function in later releases, even better!

  • run that thru the Ruby script to get the 4-bit encoded data TIC-80 wants

that means we must install ruby just to use this??... wont be better an .exe file?... or a java one at least? ... chances are we already have java installed ... or python at least

@joshgoebel
Copy link
Collaborator

I'm just being realistic and setting expectations. I doubt we'd ever build in a wav importer because I don't think importing 1/60s wavs into waveforms is a useful thing for most people. What you want for a "mod file" like experience is much longer audio samples of real instructions, and TIC-80 4-bit 32 sample WAVEFORMS are not really an equivalent of that (IMHO). They are really intended for drawing different audio "shapes" (square wave, triangle wave, etc)...

I'm super curious if/when you (or someone) manages to import "woof" into a 1/60s WAVEFORM what it's going to sound like... my bet is not at all what you think.

Definitely some cool ideas for an external tool though and again as I said I've pretty much laid out exactly how you (or someone else) would go about doing it - and given you all the tools necessary.

Prove me wrong and I'll be amazed and eat humble pie. :-)

@joshgoebel
Copy link
Collaborator

that means we must install ruby just to use this??.

Ruby is just what I know so I could eyeball the code as correct... Ruby is pretty easy to install in the *nix/Mac world (if it's not already present) - I have no idea about Windows, sorry. As I said you could ask ChatGPT to write it for you in a different language, but yes then you might need to be a programmer to read it and compile it to an EXE, etc... Ruby is nice because it's a scripting language, no compiler needed, just the runtime.

I use homebrew on Mac and it took only 5 seconds to install sox with brew install sox... it's probably(?) possible to install on Windows as well, but I dunno the steps.

@atesin
Copy link
Author

atesin commented Apr 8, 2023

edit: i shrinked the text a little

What you want for a "mod file" like experience is much longer audio samples of real instructions

I DON'T WANT A "MOD FILE" EXPERIENCE NOR IMPORT LONG SAMPLES, I AM NOT A FOOL.... I HAD WORKED WITH AUDIO BEFORE.... I HAD WORKED WITH CONSTRAINED PLATFORMS LIKE REAL ATARIS

I JUST WANT SFX SOUND BETTER WITHOUT TOO MUCH HANDWORK OF TRIAL+ERROR

@joshgoebel
Copy link
Collaborator

we must install

Well, maybe... I've been writing all this for the benefit of anyone reading this (not just you)... it's possible someone else might want to take a whack at this who already has all these things installed or is on a platform that makes them super easy to access (like Linux/Mac). Maybe they are even super easy to access on Windows, I dunno - you'd have to go look.

Someone else is definitely free to jump in here and suggest alternatives for Windows that might be more accessible to Windows users....

@joshgoebel
Copy link
Collaborator

I'm pretty sure earlier you conflated samples (like recorded instruments) with TIC-80 waveforms... that's where my modfile comment came from (since modfiles have REAL sampled instruments, not just waveforms)... you have my apologies if I misunderstood.

WITHOUT TOO MUCH HANDWORK OF TRIAL+ERROR

No need to yell. Well if you're lucky someone else will come along and do all the hard work. 👽 Hopefully I've given that person a few breadcrumbs to make their work easier. 🍞

@joshgoebel
Copy link
Collaborator

joshgoebel commented Apr 8, 2023

So far I've had 0 luck getting two waveforms to "merge" (ie, one play right after the other) regardless of what tempo/speed settings I use in the music editor... if this (wave 0 + 1) was played properly back to back it should sound like a single wave, without a glitch every time the waveform switches.

But no, you can hear a click every time the waveform changes.

Screen Shot 2023-04-07 at 10 51 20 PM

Screen Shot 2023-04-07 at 10 51 34 PM

@bztsrc
Copy link
Contributor

bztsrc commented Apr 8, 2023

I've put together a simple .wav to .tic converter, and since I don't know your OS, I've compiled it under Linux and Windows as well. Has no dependencies, CC-0 licensed (public domain), and source included.

wav2tic.zip

It supports mono and stereo .wav files, with unsinged 8-bit, signed 8-bit, 16-bit, 24-bit and 32-bit floating point samples. To convert multiple .wav files, simply add more on the command line. The first .wav file will become the first TIC-80 waveform, the 2nd the 2nd etc. It does not do HZ conversion or anything fancy, it just reads the first 32 samples from the .wav files for each TIC-80 wave (so use properly converted .wav). It outputs output.tic, which then can be loaded in TIC-80.

I only did basic tests, if you have any issues, let me know and I'll fix.

Hope this helps,
bzt

@joshgoebel
Copy link
Collaborator

knows this obscure sox format, but they all know wav format.

Again, It's a tool, not a format.

Audacity has far superior filters and conversion features than this sox tool

Perhaps, though all I see here is a claim, not any evidence to that effect. 😇 CLI software can be just as powerful and capable as GUI for those who know how to use it. Just because you've never heard of it doesn't make it crap. :-)

@bztsrc
Copy link
Contributor

bztsrc commented Apr 8, 2023

It makes no sense to add yet another tool and further dependencies into the toolchain if Audacity is already there and can perfectly do the job.

Specially since the OP isn't familiar with sox, furthermore he named Audacity explicitly as a preferred tool (and Audacity can export raw (header-less) PCM in the first place, no need to use sox for that).

FYI, if the OP would have asked about a tool that can be used in batch files then that would be a different matter, but I still wouldn't recommend using arbitrary raw binary data. Sticking to well-known formats like .wav always pays off on the long run.

CLI software can be just as powerful and capable as GUI for those who know how to use it.

Never said otherwise. I prefer CLI tools myself (check out my repos, I've created numerous CLI tools, see PICO-8 to TIC-80 for example), but 99% of the average users don't know nor like CLI, all they know is GUI (that's why I made a browser version too of PICO-8 to TIC-80).

Look, I've provided the C code to load .wav files directly and which could be merged into TIC-80, and also provided a separate tool to convert .wav files into a .tic file without any dependencies (no ruby, no libs. no installation etc. needed, it just works™). What else could I add?

Cheers,
bzt

@atesin
Copy link
Author

atesin commented Apr 8, 2023

Neither of the tools the OP mentioned knows this obscure sox
about audacity:
(not to mention the lot more user friendly interface)

i agree with @bztsrc in all those statements

i never heard of sox before.... and editing a sound file by command line would be like trying to edit an image file by command line with gd or imagemagick cli instead gimp, paint.net, photoshop, corel or even mspaint (i have paint.net and mspaint installed)

why sox?, if i had audacity installed?, is free software, freely downloadable and usable, short comparatively, available in all major OS's, modular, easy, nice, powerful, etc

.. but one thing sox could serve is to look at its source code (for who knows c/c++) and get ideas to write a tic80 command/tool conversor

@joshgoebel
Copy link
Collaborator

and editing a sound file by command line

IIRC the original ask was importing / conversion, not editing.

It makes no sense

Only that I'm unfamiliar with audacity and was able to get sox to do the job in just a few min. I'm sure there are others who'd rather install a simple CLI than a bloated GUI. It's great for people to have choices.

What else could I add?

I dunno. I'm just waiting to see a "woof" cartridge now. :-)

@atesin
Copy link
Author

atesin commented Apr 8, 2023

I dunno. I'm just waiting to see a "woof" cartridge now. :-)

WooF = https://www.youtube.com/watch?v=kNEfRhmhP80

if this cmd/tool would exists, the woof sound could be replaced/improved in this nice game = https://tic80.com/play?cart=1483

i agree with you in the sense different users feel different comfortable with a cli or gui external conversion utility (but i still dream tic80 will have builtin conversor+importer in the future :) )

... but in my case, tic80 wav conversion is not the only thing i will use audacity, i also use it to clean old recordings from cassette (my mother has boxes full of them), or to process myself speaking/singing (for dubbing for example), or to get samples to make remixes in fruitloops/lmms... but for who only need to preprocess tic80 wavs or feel more comfortable with it, sox would be also perfect....

IIRC the original ask was importing / conversion, not editing.

i agree with that either

@bztsrc
Copy link
Contributor

bztsrc commented Apr 8, 2023

if this cmd/tool would exists

have you seen #2162 (comment) ?

Cheers,
bzt

@joshgoebel
Copy link
Collaborator

It supports mono and stereo .wav files, with unsinged 8-bit, signed 8-bit, 16-bit, 24-bit and 32-bit floating point samples.

Is this code on github? If so I'd be curious for a link to the downsampling code.

@bztsrc
Copy link
Contributor

bztsrc commented Apr 8, 2023

Is this code on github? If so I'd be curious for a link to the downsampling code.

Yes, obviously...

It is right here, in this topic, as an attachment to #2162 (comment) and as I've said, CC-0 licensed, source included in the zip (just ca. 50 SLoC, as simple as it gets).

I've also said that it does not do Hz conversion or anything fancy stuff, it just takes 32 samples from the .wav and saves those samples in .tic format. That's all it does.

Cheers,
bzt

@joshgoebel
Copy link
Collaborator

It is right here, in this topic, as an attachment

No I meant a repository here on Github so I can read and see the code here on the net (and perhaps watch it change over time, or even contribute, I'm not interested in a unchanging zip file...

@atesin
Copy link
Author

atesin commented Apr 9, 2023

i have another idea ...... i think would be super easy to developers, to add a command to import (copy) waveforms from one cartridge to another, from one slot to another :) .. something like:

> import sfx id=3 soundlib.cart id=7

do you get the idea? ... this would be a excelent combination with the importer tool.... with this function we could add sounds to our catridge on the progess, without the need to start a project from scratch from a blank cartridge with sounds generated by the tool, and will gives us the possibility to organize and manage our sounds and create library cartridges, and re-use our sound banks for other projects :)

@bztsrc
Copy link
Contributor

bztsrc commented Apr 9, 2023

No I meant a repository here on Github so I can read and see the code here on the net

We are bit lazy and demanding, aren't we? Nope, I've created the solution and uploaded it here, and I'm not planning to create a repo for it. I already have way too many repos to maintain, plus I got much bigger fish to fry.

I was mentioning the CC-0 license to tell you, you can do whatever you want with it, including creating a repo for it if that's what you want.

I'm not interested in a unchanging zip file...

That's all you got. Don't be lazy, just click on it and open main.c in Notepad. You can take a look at the source if you really want to. (But as I've said, nothing special, it just copies 32 samples from .wav to .tic format, that's all, nothing extraordinary or interesting).

i think would be super easy to developers, to add a command to import (copy) waveforms

I agree the perfect solution would be not this tool but to have an integrated command in TIC-80 to import .wav files. Open call to anyone: feel free to use the C code in my tool to implement this.

Cheers,
bzt

@joshgoebel
Copy link
Collaborator

We are bit lazy and demanding,

It was clearly a question, not a demand.. 🤪 Perhaps a little lazy - but bigger picture it's more about long-term thinking, can I contribute, report bugs, etc... it sounds like you have too many other things on your plate, which makes me less interested. I don't really want to "own" the code (and its' bugs) either, but perhaps could have wanted to contribute.

I already have way too many repos to maintain, plus I got much bigger fish to fry.

Fair. I hear you on that.

@atesin
Copy link
Author

atesin commented Apr 10, 2023

i think would be super easy to developers, to add a command to import (copy) waveforms

I agree the perfect solution would be not this tool but to have an integrated command in TIC-80 to import .wav files. Open call to anyone: feel free to use the C code in my tool to implement this.

yes, but this is a little different than the solution we are discussing here (an internal/external command to import a .wav into cart)

... with this new idea i mean.. an internal command (ideally) that just open a .cart file and READ bytes in CHUNK_WAVEFORM area ... then COPY to ram WAVEFORMS area (0x0FFE4) .... copy waveforms from some other catridge, one-to-one, to the cart loaded in ram (assuming no conversion needed).... from one slot to another

just copy data as is, from there to here... or if loading data into ram is hard, at least from one .cart file to another .cart file

@atesin
Copy link
Author

atesin commented Apr 10, 2023

@bztsrc : could you please include some readme/man file or something, with more detailed information on how to use wav2tic ?? ... because the help page is also very swallow xD .... you know how this tool work, you wrote it.. but we dont and you should teach us how to use it, like a kid

requirements, arguments, etc .. what means -u? ... will work with any .wav file? ... how to make if i want to place lats say in slot 5 ??, will it work with existing .cart files??, without messing the rest of cartridge?? ... etc etc

can it take soudforms from clipboard?? (supposing we have open audacity or similar, and we just select an audio slice an copy to clipboard)

can waw2tic read a .wav and load into currently loaded cart? (ram)

could wav2tic copy soundforms from one cartridge file to another catridge file? .. from/to arbitrary slots?? ... etc etc

thanks

@atesin
Copy link
Author

atesin commented Apr 15, 2023

hey... i discovered you can copy an instrument from one open cartridge to another...

now i have 2 tic80 running instances, so i can copy one sfx from an old project to my new project .... they copy envelopes from one of 64 instrument slot to another, and waveforms from one 16 slots to another, using the clipboard buttons ^^D

... so half or my questions above are answered... maybe tic80 clipboard format could be exploited in some other tool

@bztsrc
Copy link
Contributor

bztsrc commented Apr 15, 2023

Fair. I hear you on that.

Sorry that I can't help more. But I believe I have provided everything needed to implement this.

could you please include some readme/man file or something, with more detailed information on how to use wav2tic ??

No need, it is really this simple.

wav2tic [-u] <wav> [wav [wav ...]]

-u: .wav has unsinged 8-bit samples

what means -u?

As the usage says (for some reason beyond my comprehension Audacity can only save unsigned values for 8-bit... Not with the other variants (16-bit, 24-bit, 32-bit, float), those are all signed as should be...
audacity_wav_export
Sadly this information isn't stored in the header and other tools like FT2, MilkyTracker, OpenMPT, etc. can work with both signed and unsigned samples,
ft2_sample_editor_sign
so these other than Audacity tools tend to export signed 8-bit samples as expected, hence the -u option. Would be better if all tools would save signed 8-bit, or if there were a flag in the .wav header to tell if the samples are unsigned, but there isn't.)

will work with any .wav file?

Yes, mono/stereo, 8-bit, 16-bit, 24-bit, 32-bit and float samples too (everything except the proprietary PCM encodings). For best results, use only mono .wav files which have exactly 32 samples.

how to make if i want to place lats say in slot 5 ??

As I wrote here, each .wav file will be loaded at the next free slot. I you want a specific .wav to appear at slot 5, you'll have to add 4 (possibly silence) .wav files before.

can it take soudforms from clipboard??

Nope. This is as simple as it gets, it just reads files, and saves output.tic.

can waw2tic read a .wav and load into currently loaded cart?

Nope, this is a command line tool. To read samples into the currently loaded cart, you'll need TIC-80 and a currently loaded cart in the first place... You'll have to implement the import sfx command in TIC-80 using this code for that.

Cheers,
bzt

@atesin
Copy link
Author

atesin commented Apr 16, 2023

thank you....

one last question.... which frequency (or note) the imported .wav file should have to fit in a tic80 waveform slot?? .... because as i understood, that 32 samples means a single cycle, then that soundwave will be stretched across time according the note is being played

so if i save the .wav file lets say at 150hz and import to tic80 soundform, but tic80 waveforms are 300hz (as examples), then i will be importing just half cycle... same the opposite, if i save a 600hz .wav and import to tic80 then my sample will sound too pitched and i will lose resolution

or like somebody said above, that a single cicle lasts 1 tick (1/60 sec), in which case a single waveform will have 60hz ?? ... or depends on other conditions?

@bztsrc
Copy link
Contributor

bztsrc commented Apr 16, 2023

Neither, these are much higher level concepts, and as I've said, wav2tic does not do any of that: no Hz conversion, nothing fancy. It cares about the format representation only. It just takes 32 samples from the .wav, and saves as TIC-80 and that's it. That's why I wrote you should prepare the wave beforehand in Audacity to have exactly 32 samples (which could be 2 secs with 16Hz or half a sec if it's 60Hz, doesn't matter, only the number of samples matters).

This PoC proves that TIC-80 could be able to import .wav files; one can add these high-level resampling / retuning etc. filters later, when the .wav import is already working (independently to the format representation). FYI don't expect good results from these filters, not much point in converting sophisticated wave samples into chiptunes (with only 16 different possible values in each 32 samples).

Cheers,
bzt

@atesin
Copy link
Author

atesin commented Apr 16, 2023

hi @bztsrc ... maybe i didnt explain myself enough

i understand wat2tic doesn't make any sound processing nor conversion (other than signed/unsigned), but just read the .wav file, take it here and put in there

i meant... when i am sampling the sound, with audacity or similar, and i select a slice that i think it sounds clear, and before save the .wav file i should stretch the sound frequency (resample?) to adapt tic80 to fit in his wafeform slot.... as part of the work we do in our sound editor gui/cli program

so... which is the frequency we should pitch our samples in our sound editor program before saving to .wav, to make them coincide tic80 waveform slot ... is it 60hz?... imagine this bad example:

image

@bztsrc
Copy link
Contributor

bztsrc commented Apr 16, 2023

Here's a slightly modified version. For convenience I've swapped the signedness to match Audacity's, so this assumes unsigned 8-bit data by default, and requires the -s flag for signed samples.
wav2tic.zip

which is the frequency we should pitch our samples in our sound editor program before saving to .wav, to make them coincide tic80 waveform slot ... is it 60hz?

This should be obvious. Frequency is the number of samples per second, so it depends on the length of your wave. For example, if you have 2 secs of wave, then frequency has to be set to 16 Hz to get 32 samples. If your wave is 1 sec in length, then your freq would be 32 Hz to get 32 samples.

But you don't have to do this calculation yourself, Audacity is perfectly capable of working with the number of samples. Just click on "s" after the time, and select "samples".

imagine this bad example

I believe you still don't understand what chiptune is. As @joshgoebel said, 32 samples isn't much. It is actually a very very extremely low number of samples, only capable of doing chirps and beeps. Do not expect a dog's woof with such a low resolution (32 samples of -8..7), that's never going to happen.

Try something like this instead:
wav2tic_example

Cheers,
bzt

@atesin
Copy link
Author

atesin commented Apr 17, 2023

so the answer is 32hz ??? or 1hz ?? ... 440hz?... 1378.125hz??

image

i understand that with common sampling rates, 32 samples is very short, just about a click sound, less than a click, the click of a click, actually a single cycle of 1000hz have JUST 1ms!, barely audible .... i believe tic80 plays this single cycle in loop, at different speeds according note, that is because it seem to be continuous and larger.... if we vary some dots in waveform it seem to change harmonics and will sound like another different thing

so, if the sound has for example 44100hz resolution, each sample is taken each 1/44100sec = about 0.000023 secs! .... yes but i have to stretch and resample that sound to make it fit with tic80 waveform single cycle, and export just a single cycle that fits within there..... another info that could be useful is tic80 sound sampling rate in hz that is not mentioned anywhere, to do calculations.... in other words

i think... in audacity at least, with sampling rate of 44100hz, to make a single cycle have 32 samples, i have to stretch+resample any sound to 44100/32 = 1378.125hz... that way if i zoom the sound enough it look like cycles have exactly 32 samples:

image

generated sine wave of 1378.125hz, zoomed to 1 cycle

i can't make it work.. it stills looks a single high dot in tic80 waveform... maybe are the id3 tags? but i dont add any... i also tried exporting with nyquist wav 8bit signed format but the same

so back to original question.... which freq to STRETCH+RESAMPLE sound to make 1 cycle have 32 samples??, 32hz ??? or 1hz ?? ... 440hz?... 1378.125hz?? ... some formula??.. it depends on something else?

p.s.: about -u .... i did learn a little more about exporting thanks to you, but i think the original wav2tic sign handling is ok because it uses defacto standard and rarely audacity doesn't ... a better improvement could be to supply an output file name to "inject" wavs, but may be a little harder, perhaps in some future :) (be patient, atesin!)

@bztsrc
Copy link
Contributor

bztsrc commented Apr 17, 2023

i believe tic80 plays this single cycle in loop, at different speeds according note, that is because it seem to be continuous and larger

Yes, exactly. That's why there's no point in talking about the frequency of one wavepattern. It only has a frequency when actually being played as a note.

another info that could be useful is tic80 sound sampling rate in hz that is not mentioned anywhere

That's because there's no such thing. You have 32 samples, which are repeatedly taken. How often the pointer jumps to the next sample in the wavepattern depends on the pitch, TEMPO and SPEED values when it's being played. Of that I'm certain, but how exactly pitch, TEMPO and SPEED is used to calculate the duration of a single sample (which would be needed to tell the Hz) is a mystery to me, and sadly @nesbox did not answer my question here nor your question here. So we can only guess...

that way if i zoom the sound enough it look like cycles have exactly 32 samples

Right, but your problem is, it shouldn't be just one cycle when you zoom in, rather the entire wave altogether can't be longer than 32 samples. That's why you're getting bad results.

In other words, the .wav file must be 76 bytes long, no more (assuming no meta info). To give a fully technical and proper explanation, if you take a look at the .wav with a hex viewer, you should see that the "data" chunk's length is 0x20, aka. 32 bytes exactly (for mono 8-bit samples), regardless to the frequency.
wavdump

Hope this helps,
bzt

@atesin
Copy link
Author

atesin commented Apr 18, 2023

wavepattern depends on the pitch, TEMPO and SPEED values when it's being played.

you are right

that way if i zoom the sound enough it look like cycles have exactly 32 samples

Right, but your problem is, it shouldn't be just one cycle when you zoom in, rather the entire wave altogether can't be longer than 32 samples. That's why you're getting bad results.

actually the test i did is to generate a mono sine wave of 1378.125hz 1sec duration... then zommed, then select a single cycle and noted it has exactly 32 samples... then i copied the selection (1 cycle, 32 samples) and PASTED to a new project... then export the 1 cycle 32 samples project to .wav 8bit, not the 1sec lenght one

i understand there is no way i could fit 1sec sound in a 32 samples slot .. for god sake, don't make me repeat this again :(

which i want to know is to which frequency i should stretch+resample my sound (whatever frequency and lenght it has), in order to make each cycle have exactly 32 samples... so that exporting a single cycle would fit exactly in tic80 waveform slot window .... i dont care the later playing speed

for example...

(extract, actual sound is larger)
image

zoomed in to view 1 cycle
image

need to be resampled before exporting... to make the same sound more pitched, enough to make cycles fit in tic80 wave slots .... so that for example, if i play that sound in tic80 at G-3 (~200hz), it sounds "similar" to original sample (or at least recognizable.. i know it will sound more distorted)

..... so... to what frequency we have to stretch samples before exporting, to make it tic80 wave slot holds exacly 1 cycle of that sound?? (neverthless of playing speed)

p.s.: i can't make wav2tic work properly... maybe the windows version has some issue/dependency

@bztsrc
Copy link
Contributor

bztsrc commented Apr 18, 2023

i want to know is to which frequency i should stretch+resample my sound (whatever frequency and lenght it has), in order to make each cycle have exactly 32 samples

It's not "make each cycle 32 samples". You must fulfill the equation freq*total wave length=32 to get 32 samples in total.

so that exporting a single cycle would fit exactly in tic80 waveform slot window

I've achieved this by using 32Hz and making the entire wave 1 sec long. But other combinations will work too, it is just 32Hz/1sec is the simplest to work with.

Is this extremely short? Yes, you're right it is. And even its precision is limited to the -8..7 range. This can really just store some rudimentary chirp or beep.

to what frequency we have to stretch samples before exporting, to make it tic80 wave slot holds exacly 1 cycle of that sound?

If you were asking about MEG-4, then I could properly answer you question: the output audio freq is set to 44100Hz, feeded at 50Hz, one wavepattern can be 16376 samples long each in the range -128..127 tuned at 262Hz pitch, and for playing that wave at grand piano's middle C it needs 882 samples per tick (because 44100/50*262/262=882). (Eh, 428 is the period of C-4, it's freq is 262Hz)

No clue how this is calculated in TIC-80 though, sorry. :-( The TIC-80 wiki isn't helpful, it only says this calculation is done, but does not say how exactly: The frequency value is converted to a period value (clamped to 10...4096) suited for a virtual 2,088,960 Hz clock. This period value produces an update frequency that is close to 32*frequency (for waveform envelopes) or 16*frequency (for noise output). Total gibberish, right? Period value of what? And without knowing how long one sample lasts, it is impossible to tell what the output frequency actually is (is it 32*2,088,960/4096=16kHz tops?), so I don't know how to resample/stretch your wave in Audacity so that it will be reproduced at the same freq in TIC-80, sorry. Use trial-and-error, that's the best advice I can give you.

i can't make wav2tic work properly... maybe the windows version has some issue/dependency

In the first version I forgot to account for the chunk's length that's also stored in the data chunk, so it reads 4 bytes shorter wave (with mono 8-bit that's 4 samples short, with stereo 16-bit that's 1 sample short). Anyway, this has been fixed in the last version. Neither the Linux, nor the Windows version has dependencies whatsoever, btw.

Cheers,
bzt

@bztsrc
Copy link
Contributor

bztsrc commented Apr 18, 2023

i want to know is to which frequency i should stretch+resample my sound (whatever frequency and lenght it has), in order to make each cycle have exactly 32 samples

I'll try to explain why your question doesn't make sense, but I must stress I'm not sure about the TIC-80 part.

Let's assume we have fixed frequency (let's say 44100Hz), that means 44100 samples are played in each second.

       one cycle
 /------------------\
 ###                 ###                 ###
 ###                 ###                 ###
+---++---++---++---++---++---++---++---++---++---+   (10 samples)
---------------------------------------------------> time

To change the pitch, you make the peeks in the samples more dense (or you use more gaps between them), like this:

    one cycle
 /-------------\
 ###            ###            ###            ###
 ###            ###            ###            ###
+---++---++---++---++---++---++---++---++---++---+
---------------------------------------------------> time

Note that the number of samples changed within one cycle, however the overall number of samples in a second hasn't, that latter is still 44100 samples per second. Therefore, no matter the pitch, one sample is played for 1/44100 seconds long.

This is how Audacity handles things and this is what you're asking about when you talk of cycles.

However, if I'm correct this isn't how TIC-80 works at all. As far as I can tell, it instead messes with the update frequency, like this:

   one cycle
 /----------\
 #           #           #           #
 #           #           #           #
+-++-++-++-++-++-++-++-++-++-++-++-++-+
---------------------------------------------------> time

Now the number of samples in a cycle hasn't changed, but the number of samples in a second did. Despite of the same wavelength, the peeks in the wave got closer in time, so the pitch indeed changed in this case too.

To get the wave's frequency you should not ask how many samples are there in a cycle, rather you'll need to know for how long one sample is played for a certain pitch (a question that the wiki does no answer well, so I dunno :-( ).

But I'm no expert on TIC-80 sounds, so we really need @nesbox to confirm this. Until then, trial-and-error is you best shot to get the same pitch in both Audacity and in TIC-80.

Cheers,
bzt

@atesin
Copy link
Author

atesin commented Apr 18, 2023

yes i know by stretching/resampling sounds a kind of interpolation is made... sampling rate is not changed... like shown in this example:

image

let me express my doubts in another way...

in other words.... imagine i have a repetitive sound like me saying "aaaaaa", in a common .wav or .mp3 file (*)
.. what processing should i apply to sound, to finally make tic80 play it and be (kind of) recognizable??

... in other words... how can i make tic80 play "aaaaaa" with my voice (more or less), if i had recorded previously?

.... or if i have, let's say, the recording of a clarinet.... what should i do to copy that sound (a single note) to tic80 and make it sound aprox. like that clarinet?

.... all of these suposedingly without shifting notes in tic80... i mean if we play a C-5 it sounds with the frequency of a C-5, while making sound still rather identifiable

(*) common format: like 44100hz sampling rate, 32bit resolution, stereo, 128kbps or more

@bztsrc
Copy link
Contributor

bztsrc commented Apr 18, 2023

sampling rate is not changed

Yes it is changed, on the TIC-80 side. I'm certain of that, I just don't know how much it changes for a certain pitch.

what processing should i apply to sound, to finally make tic80 play it and be (kind of) recognizable??

No such processing exists.

what should i do to copy that sound (a single note) to tic80 and make it sound aprox. like that clarinet?

I've said this multiple times, don't expect any recognizable sounds, no matter what filter/resampling/whatever magic you use. No dog's woof, no "aaaaa", no clarinet, no nothing. Just chirps and beeps, that's the best 32 samples in the range -8..7 will give you.

Cheers,
bzt

@atesin
Copy link
Author

atesin commented Apr 18, 2023

sampling rate is not changed

Yes it is changed, on the TIC-80 side. I'm certain of that, I just don't know how much it changes for a certain pitch.

right... but i meant in a sound editor program... when you change the tone or apply some effect to some sound it does by interpolation not by changing sampling what keeps constant everytime (unless you change through menu/tool).... but for tic80 i am sure is easier and cheaper to achieve tones by changing sampling rate instead doing interpolation

what processing should i apply to sound, to finally make tic80 play it and be (kind of) recognizable??

No such processing exists.

if you read a little more carefully you will realize i used sentences like "kind of", "more or less", "aprox.", "still rather", etc ... I AM TOTALLY AWARE IT WON'T SOUND PERFECT ...

i feel you treat me as if i would fool or ignorant .... i worked on ataris when i was in the school making programs in basic, and worked as dj when in college, so i know something about microcomputers and music

it can't be, there must be some way(s) to do it, with the help of your tool... even you converted a sine sound to be exported to wav, to be imported to tic80, and worked... what i am asking is not to only convert 1hz 32samples generated waves, but also any other sampled sound whatever it ends sounding in tic80... we have all the tools

try to be more imaginative

@bztsrc
Copy link
Contributor

bztsrc commented Apr 18, 2023

what i am asking is not to only convert 1hz 32samples generated waves

The tool does not only work with generated waves, you can supply whatever data you'd like. But the wave has to be 32 samples long in total, because there's no more storage space in the TIC-80's memory. There's nothing you can do about that limitation (unless you rewrite TIC-80 itself to support more).

try to be more imaginative

I am. That's why MEG-4 SFX stores waves up to 16376 samples with the resolution of -128..127. That's still a chiptune and distorted like hell, but at least that's enough information to do what you're asking for. (Check out the demo, around 1min there's a man shouting "come on". Not perfect by any means, but clearly recognizable.)

32 samples with the resolution of -8..7 loses so much of the wave data that it's simply not enough information to be recognizable. That's why people call it a chiptune and not audio.

Cheers,
bzt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants