Making WAVs: Understanding, Parsing, and Creating WAV Files in JavaScript

แชร์
ฝัง
  • เผยแพร่เมื่อ 21 ส.ค. 2024
  • The WAVE file format is a binary format that encodes high fidelity audio data. But how is the audio encoded and stored? How can these files be read and created in JavaScript? That's what we'll find out in this video!
    =[ 🔗 Links 🔗 ]=
    💌 Updates to your inbox: tinyletter.com...
    ⭐️ Patreon: / lowleveljavascript
    💻 Github Repo: github.com/Low...
    github.com/fra...
    github.com/fra...
    soundfile.sapp....
    en.wikipedia.o...
    www.tactilemedi...
    en.wikipedia.o...
    en.wikipedia.o...
    github.com/fra...
    github.com/fra...

ความคิดเห็น • 107

  • @linnickschlanter4712
    @linnickschlanter4712 3 ปีที่แล้ว +66

    I have no idea about JS and was just looking for informations about the structure of wave files, after your video i feel very comfortable to handle those in python now, thank you!!

    • @LowByteProductions
      @LowByteProductions  3 ปีที่แล้ว +11

      Glad it was helpful to you. I intentionally made this video so it was less about language specifics and more about formats.

    • @ScientObject40
      @ScientObject40 6 หลายเดือนก่อน

      I'm in the exact same situation.

  • @patrickjdarrow
    @patrickjdarrow 2 ปีที่แล้ว +10

    What a ridiculously thorough but concise video. Exactly what I needed after being disappointed by the wiki page. Keep it up man!

  • @F0F0717
    @F0F0717 3 หลายเดือนก่อน

    I’m not specialist with computer or even coding , these all are new information for me , i think i took more additional formation
    Thank you so much 🙏🏼

  • @micnic90
    @micnic90 4 ปีที่แล้ว +19

    Very nice explanation, would like to see more videos of this kind. I created a few years ago a parser for WebSocket protocol in vanilla JS, arcsecond seems to ease the process of parsing a lot thanks for sharing it, it may be an idea for your future videos to analyze binary protocols and file formats.

  • @SyncVFX
    @SyncVFX 2 ปีที่แล้ว +6

    Thanks. I am working in java on a project. I needed to know the structure of wave files and how to parse them. This helped even though you use JS. Good job being language agnostic!

    • @LowByteProductions
      @LowByteProductions  2 ปีที่แล้ว +2

      Glad it was helpful - it was a conscious choice to keep the information about the format language agnostic, while keeping the js parts widely applicable as well.

  • @ktknoks8718
    @ktknoks8718 4 ปีที่แล้ว +6

    This is amazing. It's fascinating to see how powerful JS really is (thanks to libraries ofc), when it is often perceived as a "language for developing websites". Keep going!!!

    • @necroowl3953
      @necroowl3953 3 หลายเดือนก่อน +1

      It is impressive, but keep in mind that it is still terribly inefficient

  • @sviat2459
    @sviat2459 2 ปีที่แล้ว +1

    Thank you a lot mate. I'm a web dev and hadn't known about such low-level things. I want to make some beat detector on node and now I'm studying "sound" and how to do this detection. Previously I hadn't known anything about sound/bitrates/discretization/frequency etc. After watching your video I believe I should extract the sample data and just find the Extremum of every sample to find the most strong noise. So will be working in this way. Thank you again! You're the best JS dev I've ever known.

  • @viticoinf
    @viticoinf 4 ปีที่แล้ว +5

    Congrats! I really enjoyed this video, finally someone that writes real code and does something that not many developers dare doing. Looking forward to see more videos like this one.

  • @padmagullipalli4225
    @padmagullipalli4225 8 หลายเดือนก่อน

    SOO NICE ,, I AM SEEING SO MANY VARIANTS IN YOUR VIDEO MAKING , NICELY DONE IT , FORMATING WELL
    GREAT INFORMATION , NARRATING WITH DIFFERENT TYPES OF SLIDES

  • @almircampos
    @almircampos 2 ปีที่แล้ว

    Excellent! Excellent! Excellent!

  • @breezyx976
    @breezyx976 ปีที่แล้ว

    This helped me understand PCM format, very helpful, thanks!

  • @khaleddd
    @khaleddd 4 ปีที่แล้ว +3

    Thank you man! Continue.

  • @sphereornament276
    @sphereornament276 ปีที่แล้ว

    Really beautiful video! I'm really impressed by the quality and level of professionalism

  • @thecout3170
    @thecout3170 2 ปีที่แล้ว

    Very very nice explanation, i just meet the channel and its one of the best i have ever seen. Congrats!.

  • @raffaelrameh14
    @raffaelrameh14 2 ปีที่แล้ว

    What a Channel!!!!!!!! S2

  • @ziyadcodes
    @ziyadcodes ปีที่แล้ว

    Thank you soo much, that was one of the cleanest tutorials I've ever seen

  • @whamer100
    @whamer100 4 ปีที่แล้ว +3

    very big fan of this! i cant wait to see what other kinds of parsers and stuff.
    idea: write a wasm parser (maybe even a sort of assembler or smth)

    • @Sidney600MC
      @Sidney600MC 4 ปีที่แล้ว

      o hi

    • @whamer100
      @whamer100 4 ปีที่แล้ว

      @@Sidney600MC oh hey sidney

  • @varunkoganti9067
    @varunkoganti9067 2 ปีที่แล้ว

    100/10 my rating for this video, so much useful dude

  • @antigonemerlin
    @antigonemerlin 5 หลายเดือนก่อน

    You can do this with regular ol' web JS too by using to upload a binary file, and then you can just open up the blob, convert to either a Uint8Array or a Uint32Array, and work from there.

  • @BusinessWolf1
    @BusinessWolf1 ปีที่แล้ว

    That was incredible.

  • @svndays
    @svndays 3 ปีที่แล้ว

    Great video! Very helpful in understanding wav files, and highlights some very cool libraries.

  • @sleepcycle_
    @sleepcycle_ 3 ปีที่แล้ว

    I'll make waveform like Sound cloud waveform in my app! Thank you for your video. I was really really helped for you.

  • @AJSquirrel53
    @AJSquirrel53 2 ปีที่แล้ว +1

    So cool! Thanks!

  • @hros2671
    @hros2671 3 ปีที่แล้ว

    Pretty profesional dedicated video, thank you so much!

  • @gatty.
    @gatty. 3 ปีที่แล้ว

    So useful! Thank you for your video. I think this will go great with Fabfilter's bitrate video and such.

  • @Speykious
    @Speykious 4 ปีที่แล้ว +3

    It's also just as I was interested in decoding audio formats. For example, to make a customizable audio spectrum in Rust (I've seen great sketches already in js). But decoding compressed audio files is complicated 7_7
    And I can imagine how difficult it would be to decode video compressed files as well.

    • @LowByteProductions
      @LowByteProductions  4 ปีที่แล้ว +10

      I like to think of it like: Things you don't know how to do are impossible, but once you find out how to do them, they just become hard. And in comparison to impossible, hard is easy!

    • @beepbeepimasheep237beepbee3
      @beepbeepimasheep237beepbee3 2 ปีที่แล้ว

      @@LowByteProductions Hard is easier than impossible, right?

  • @ManontheBroadcast
    @ManontheBroadcast 4 ปีที่แล้ว +3

    Can't thank you enough! ...

  • @calixtetayoro5719
    @calixtetayoro5719 4 ปีที่แล้ว +2

    pure #CodeGasm... thx for the ride!

  • @devinh.9683
    @devinh.9683 4 ปีที่แล้ว

    your videos are amazing! Thank you so much!

  • @jackvial5591
    @jackvial5591 3 ปีที่แล้ว

    Thank you! Fantastic content

  • @j7ndominica051
    @j7ndominica051 ปีที่แล้ว

    An annoying extension of the wave format has become common: waveformatextensible. It has a codec id of FFFE or -2 and a longer 'fmt ' chunk to encompass additional fields and the actual format as a long ass GUID, because in the Microsoft universe you will no doubt have quadrillions of formats. It can be treated in place as codec 1 (int) or 3 (float).
    You can probably accept files with extra data at the end. It could be a metadata tag not included in the chunk structure or unknown data after extraction from a package without determining the length of the file.

  • @emiliogaelmarcoscabrera3449
    @emiliogaelmarcoscabrera3449 9 หลายเดือนก่อน

    great video!

  • @joao.henrique
    @joao.henrique 2 ปีที่แล้ว

    Amazing video, thank you very much :)

  • @goji5887
    @goji5887 3 ปีที่แล้ว

    Hehehe i can hear you in there, fellow Dutchman. Your subtle accent betrays you! Still very subtle though, so props on your good English

    • @LowByteProductions
      @LowByteProductions  3 ปีที่แล้ว +1

      hahaha eigenlijk kom ik uit Engeland, maar ik heb zo lang in Nederland gewoond dat nu heb ik een klein beetje accent 😂

  • @fakhry3021
    @fakhry3021 8 หลายเดือนก่อน

    amazing thank you!

  • @AndersonSilva-dg4mg
    @AndersonSilva-dg4mg 4 ปีที่แล้ว

    Thank you! Continue.

  • @rickarmbruster8788
    @rickarmbruster8788 3 ปีที่แล้ว +1

    Even myself as a C++ dev has respect for this JavaScript channel. Do you know how to interpolate a 22050 8 bit Depth WAV to a 44100 16 Bit one?

    • @LowByteProductions
      @LowByteProductions  3 ปีที่แล้ว +1

      Double up the samples and use linear interpolation to map values in 0x00 - 0xff to the 0x0000 - 0xffff range. Should correctly account for twos complement encoding as well.

  • @SirusStarTV
    @SirusStarTV 4 ปีที่แล้ว

    Awesome video ☺️

  • @CollinBarlage
    @CollinBarlage 3 ปีที่แล้ว

    great stuff mate

  • @arcticspacefox864
    @arcticspacefox864 4 ปีที่แล้ว

    Very noice video, love it!

  • @danieliniguezv
    @danieliniguezv 3 ปีที่แล้ว

    amazing!!! thank you!

  • @unchayndspersonalaccount7690
    @unchayndspersonalaccount7690 3 ปีที่แล้ว

    I think I can answer the question at 11:46 about the BlockAlign being a non-integer. Basically, if the NumChannels is an integer (which it should be-- imagine having 3.5 channels??) and the BitsPerSample is a multiple of 8 (which should also be true-- e.g., 16-bit, 24-bit, 32-bit), it's not possible for "NumChannels * BitsPerSample/8" to return a non-integer.

    • @swaminathbera6407
      @swaminathbera6407 2 ปีที่แล้ว

      Yeah, basically odd (num of channels here) * even (bitrate) = even always. Cool!

  • @TrainingWithKona
    @TrainingWithKona 4 ปีที่แล้ว

    HTTPS connections & I/O next!

  • @AndersonSilva-dg4mg
    @AndersonSilva-dg4mg 4 ปีที่แล้ว +3

    Please tell us about PNG format

  • @rfgrooteman
    @rfgrooteman 2 ปีที่แล้ว

    Your file size checking error message should expect size + 8 bytes in comparison with file.length.

  • @batica81
    @batica81 2 ปีที่แล้ว

    Good video. Btw new version of construct-js has a lot of breaking changes. Stick with the repo for testing.

  • @masimusic316
    @masimusic316 3 ปีที่แล้ว

    my audio is very muddy and sharp tone because massive amount of vst plugins are used and I have suspicion there is some software issue with .wav file cant convert/calculate the data well, so how do I optomize windows for best .wav calculations.

  • @tails_the_god
    @tails_the_god 2 ปีที่แล้ว

    nice! very helpfull video, i was wondering if you can explain how to make an NSF file from scratch just like how you covered here BUT i dont expect you to have to go through the emulator side of it since its an NES sound format, just like go through the basics of how the file is structured and creating a parser. I made an emulator in freebasic and the next step is sound so its alot of help if there was a video covering it :)

  • @Speykious
    @Speykious 4 ปีที่แล้ว

    So great!
    Do you know about Tsoding's video about making music with Haskell, which is about generating .wav files?
    (well technically it's not really the .wav format...)

    • @LowByteProductions
      @LowByteProductions  4 ปีที่แล้ว

      I have indeed seen the video, and I love Tsoding's content

  • @a_social_engineer2230
    @a_social_engineer2230 3 ปีที่แล้ว

    incredibly useful chart in the beginning, I just paused the video and that was all I needed to process my uncompressed audio signal in C. Why does the endianness switch back and forth in between metadata fields?

    • @LowByteProductions
      @LowByteProductions  3 ปีที่แล้ว +1

      The big endian fields are actually text data, but all fit into 32 bit ints. I suppose that's just a more exact way to specify them, without having to worry about confusion surrounding encodings etc

  • @xyntho
    @xyntho ปีที่แล้ว

    Hey, great vid Francis!
    I wonder what's causing the output.result to be [ [ 'RIFF', 88236, 'WAVE' ], Object [Generator] {} ] at 12:58 of the video? It would be really helpful if you help me out :)
    I suppose ArcSecond got some groundbreaking updates to it? If yes, please can you provide a workaround over this?

    • @LowByteProductions
      @LowByteProductions  ปีที่แล้ว +1

      Hey Komi, thanks!
      Arcsecond did indeed get an update - the API for coroutine changed a little bit. If you check the docs on the github page github.com/francisrstokes/arcsecond#coroutine, you should be able to see the changes that are required.
      Hope that helps!

    • @xyntho
      @xyntho ปีที่แล้ว

      @@LowByteProductions thank you so much! Love your humble nature! I love learning from your channel because of the atmosphere in your videos is the most comfortable one I ever found on YT. Yours is the only channel on YT I follow for programming :)
      Edit: Thanks, I tried it out and it works like a charm, I love you man!

  • @jordanfox3782
    @jordanfox3782 2 ปีที่แล้ว

    Thanks for the excellent video. I am a new programmer and I am trying to create a small program that parses a wav file and does some processing with it, namely, reverse it, slow it down, make it louder and so on. Does anyone have any idea what specific parts of the file I need to manipulate and where to locate them??

  • @abdelrahman5094
    @abdelrahman5094 3 ปีที่แล้ว

    would you recommend for a totally newbie to use JS for parsing different types of files or going to some low level languages like C ?

    • @LowByteProductions
      @LowByteProductions  3 ปีที่แล้ว +3

      On that basis alone it's kind of hard to say.
      The advantage of using something like C is pretty much always going to be speed. If the problem you're solving (and the problem is rarely the parsing itself, but rather whatever you end up doing with the structured representation!) needs to be done very fast (for example: realtime transcoding), then C would certainly have an edge there. But if it's not something particularly time bound (for example: You only open and parse the file once, and the majority of the program time is spent manipulating the structure), then the expressivity you gain with a higher level language is probably going to be worth more than the speed gains. It's pretty unlikely that a complete newbie is going to be facing these kinds of constraints, however. My personal view is that expressivity is generally worth more when learning, because you can focus on the problem itself rather than surrounding details.
      The trickiest part about this question is that there is no right or wrong. It's even better if a newbie learns from both ends of the spectrum - spending some time in a high level language and some in a low level language. Tackling challenges on leetcode or hackerrank in 2 different languages will really highlight the strengths and weaknesses of the two approaches, and help develop intuition about when and where to make a particular choice.

  • @SirusStarTV
    @SirusStarTV 4 ปีที่แล้ว

    Haha, i too created binary data reading module in node.js for myself.

    • @LowByteProductions
      @LowByteProductions  4 ปีที่แล้ว

      Nice - is it open source? I'd love to take a look.

    • @SirusStarTV
      @SirusStarTV 4 ปีที่แล้ว

      @@LowByteProductions it's on a dead laptop and i think i deleted it :D

    • @SirusStarTV
      @SirusStarTV 4 ปีที่แล้ว

      @@LowByteProductions but there's c++ code for reading different types of data from memory that i put on github github.com/PogromistDev/Memory

  • @swaminathbera6407
    @swaminathbera6407 2 ปีที่แล้ว

    *Cycle duration formula seems wrong* to me (can anybody clarify) : because Hz/Hz is not seconds
    It should be number of cycles

    • @LowByteProductions
      @LowByteProductions  2 ปีที่แล้ว

      Hi Swaminath,
      I think the choice of the word "duration" was probably wrong here. What is really being calculated here is the number of samples there are in a single cycle relative to the sample rate. Hope that helps clarify things!

  • @otimjoshua3366
    @otimjoshua3366 8 หลายเดือนก่อน

    Go listen to Wav Files by Lupe Fiasco, I'm here because of its lyrical breakdown. Plus I'm a low level web scrapper.

  • @aimikedev
    @aimikedev ปีที่แล้ว

    ParseError 'endOfInput' (position 12): Expected end of input but got '0x66' Anyone get this error ?

  • @JNET_Reloaded
    @JNET_Reloaded 3 ปีที่แล้ว

    so how do i boost wav audio using php or js or html? i need to get past 100% volume, anyone help please??

  • @Speykious
    @Speykious 4 ปีที่แล้ว

    Hey I was wondering, do you have discord? Because having a community there would be awesome

    • @LowByteProductions
      @LowByteProductions  4 ปีที่แล้ว

      No I haven't made a discord for the channel (yet). The closest thing to a community there is right now is the subreddit, but it's not that lively!

    • @Speykious
      @Speykious 4 ปีที่แล้ว

      @@LowByteProductions I see.
      I guess the subreddit isn't very active because you don't have that much subscribers and views right now. So it will slowly grow along with your audience :)
      Are you interested then? Because I can set one up and invite you there.

    • @LowByteProductions
      @LowByteProductions  4 ปีที่แล้ว +1

      Thanks for the offer! But I think i will set one up myself soon 👍

    • @Speykious
      @Speykious 4 ปีที่แล้ว

      @@LowByteProductions Great! Invite us all there once you do :)

    • @moshewaitzman1297
      @moshewaitzman1297 3 ปีที่แล้ว

      @@LowByteProductions Please invite me to it when you do :)

  • @thedebbiewinner
    @thedebbiewinner 3 ปีที่แล้ว

    this is how you make sound lol

  • @marcelomay4561
    @marcelomay4561 4 ปีที่แล้ว

    What does low level mean?

  • @JuanchosMRL
    @JuanchosMRL 3 ปีที่แล้ว

    Thank you so much for this! I just uploaded a video that's about creating 'a sound from itself', like a fractal, and your awesome code made it possible. Check it out when you have the chance :) Much love and keep rockin'!!!

  •  4 ปีที่แล้ว

    What's that background?

  • @Mad3011
    @Mad3011 4 ปีที่แล้ว

    1:42 The subtle shade...

  • @user-st8bb2gs9e
    @user-st8bb2gs9e 2 ปีที่แล้ว

    yeah good video but as a noob idk how to install arcsecond / can't find anything to eyplain me how to do it... Can someone help ?
    Anyway thx for the information in the video, helped a lot :)

    • @LowByteProductions
      @LowByteProductions  2 ปีที่แล้ว

      Arcsecond is a library you can install via npm, with `npm i arcsecond`.
      If you don't know what that means, then you should google/TH-cam for "node npm tutorial" to see how to get node and npm set up on your system. Hope that helps!

    • @user-st8bb2gs9e
      @user-st8bb2gs9e 2 ปีที่แล้ว

      @@LowByteProductions wow thank you soo much for that quick reply! Should work fine with ur description ;)) thank you so much for helping me :D

  • @ahmedkaram3829
    @ahmedkaram3829 4 ปีที่แล้ว +1

    woow . i'm glad to be the frist comment

  • @pierce8308
    @pierce8308 2 ปีที่แล้ว

    Whys certain bytes are big endian encoded and rest are little endian ? Whats the purpose for having this "mixed" endianess ?

    • @LowByteProductions
      @LowByteProductions  2 ปีที่แล้ว

      It's been a while since I've last looked at the format, but if I remember correctly, the big ending values are really just strings. If you have a string of 4 (ascii) characters, you can represent that as a uint32. To make the encoding natural, the byte representing the first character is found at the most significant position, which makes it big endian.

  • @XORfun
    @XORfun 2 ปีที่แล้ว

    Using libraries is so not low level. And actually makes your code unnecessarily confusing

    • @LowByteProductions
      @LowByteProductions  2 ปีที่แล้ว +1

      Thanks for your comment Andrew. Arcsecond and construct-js are both libraries I wrote myself, from scratch, using zero dependencies. I've all but recreated their functionality on the channel across the various videos - in fact there is an entire series about building a parser combinator system.
      If you're arguing that any use of libraries makes code confusing **in general**, then I'm going to have to disagree. IMO that is sort of teetering on absurd.

  • @thecout3170
    @thecout3170 2 ปีที่แล้ว

    i have added an additional line on the code: riffChunkStruct.get('size').set(36 + soundData.length * 2);
    just because i couldn't read the new .wav file. Is that line of code right?

    • @LowByteProductions
      @LowByteProductions  2 ปีที่แล้ว +1

      I'm not at a computer to check, but if something like that line wasn't present then I would say it is probably wrongly missing indeed.

  • @few6864
    @few6864 8 หลายเดือนก่อน

    Hello, i have this fileStruct.toBuffer() is not a function when I try fs.writeFileSync(path.join(__dirname, './new.wav'), fileStruct.toBuffer());
    I didnt see anything on github, thank's you if u can help me :)