<p>Here's a potential solution that loops over all channels of a multi-channel wav file. It's not that pretty or concise, but it works.</p>
<p>First, let's grab a multi-channel wave file as a test dataset</p>
<pre><code>### Dataset Start ###

# Grab some open-access multi-channel wav data from a relatively short 3-channel 
# recording from a dodgy sonobuoy. 
# File is approximately 3MB. 
wavURL &lt;- 'https://data.aad.gov.au/eds/api/dataset/41072dc7-996b-436e-b31a-776f28de07bf/object/download?prefix=AAS_4600_ENRICH_Sonobuoy_Data/audio/20190221/INV_20190221_013959_828.wav'

# Specify the file name to save the file on your computer
wavFile&lt;-'INV_20190221_013959_828.wav'

# Call the download.file() function, passing in the URL and file name/location as arguments
download.file(wavURL, wavFile, mode = &quot;w&quot;)

### Dataset End ##
</code></pre>
<p>Now we load the data and filter it in a for-loop. We plot the unfiltered data in the columns on the left, and the filtered data in the columns on the right. I've used seewave::oscillo to view the results here and confirm that the data look filtered, but one could remove the calls to 'oscillo' if you don't care to plot the results.</p>
<pre><code># Read the first 10 ms of the data from all three channels
wav &lt;- tuneR::readWave(wavFile,header = F,units = &quot;seconds&quot;,from = 0,to=0.01)

# Placeholder for filtered data -- same size as original data
wavFiltData &lt;- wav@.Data; 

op&lt;-par(mfrow=c(3,2),mar=c(4.5,4,2,2))
for (i in 1:nchannel(wav)) {
  seewave::oscillo(wav,channel=i)
  wavFiltData[,i] &lt;- seewave::bwfilter(wav,from=7400, to=7600,channel=i)
  # Edit: replaced wavFilt in line below with wavFiltData
  # to fix the error found by WMXZ
  seewave::oscillo(wavFiltData, f=wav@samp.rate, channel=i)
}

# Convert data back into a WaveMC format
wavFilt &lt;- WaveMC(wavFiltData, samp.rate=wav@samp.rate, bit=wav@bit)
</code></pre>
<p><a href="https://i.sstatic.net/UmgHHoRE.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/UmgHHoRE.png" alt="Plot showing original wav file on left, and filtered on right" /></a></p>

CC BY-SA 4.0
2024-10-18T06:00:23.653Z
Q: I'm not good in R, but the second oscillo accesses wavFilt, which is only assigned to after the loop. Is that correct?
WMXZ
CC BY-SA 4.0
2024-10-21T00:31:20.723Z
Yes, thank you this was indeed an error -- good catch. I have replaced wavFilt with wavFiltData, which I believe should now be correct.
Brian Miller
CC BY-SA 4.0
2024-10-17T23:08:16.377Z
2024-10-21T00:33:22.663Z
2024-10-21T00:33:22.663Z
Brian Miller
<p>I'm trying to apply a butterworth frequency filter to a multichannel audio file recorded by a hydrophone array using the function &quot;bwfilter&quot; from the package &quot;seewave&quot;.</p>
<p>Is there a way that &quot;bwfilter&quot; will work for multichannel files? If not, is there another way to filter my audio files? Thank you!</p>

CC BY-SA 4.0
2024-10-11T01:25:53.193Z
Can you share what you've already tried? From the seewave documentation, it seems that bwfilter allows for the specification of channel. Might be informative if you try passing a list of channels (e.g. channels = list(1,2) or similar) and share the results. Even if bwfilter can't handle multiple channels in a single call, this suggests at the very least that one could call bwfilter for each channel individually.
Brian Miller
<filter><seewave>
How can I apply a butterworth frequency filter to multichannel audio files?
# How can I apply a butterworth frequency filter to multichannel audio files?

(Asked by: username_0 on 2024-10-10)

I'm trying to apply a butterworth frequency filter to a multichannel audio file recorded by a hydrophone array using the function "bwfilter" from the package "seewave".

Is there a way that "bwfilter" will work for multichannel files? If not, is there another way to filter my audio files? Thank you!

**Tags:** filter, seewave

> **Comments:**
> **username_1**: Can you share what you've already tried? From the seewave documentation, it seems that bwfilter allows for the specification of channel. Might be informative if you try passing a list of channels (e.g. channels = list(1,2) or similar) and share the results. Even if bwfilter can't handle multiple channels in a single call, this suggests at the very least that one could call bwfilter for each channel individually.  

---

## 1 answers

### Answer by username_1 on 2024-10-17. Score: 1

Here's a potential solution that loops over all channels of a multi-channel wav file. It's not that pretty or concise, but it works.

First, let's grab a multi-channel wave file as a test dataset

```
### Dataset Start ###

# Grab some open-access multi-channel wav data from a relatively short 3-channel 
# recording from a dodgy sonobuoy. 
# File is approximately 3MB. 
wavURL <- 'https://data.aad.gov.au/eds/api/dataset/41072dc7-996b-436e-b31a-776f28de07bf/object/download?prefix=AAS_4600_ENRICH_Sonobuoy_Data/audio/20190221/INV_20190221_013959_828.wav'

# Specify the file name to save the file on your computer
wavFile<-'INV_20190221_013959_828.wav'

# Call the download.file() function, passing in the URL and file name/location as arguments
download.file(wavURL, wavFile, mode = "w")

### Dataset End ##

```

Now we load the data and filter it in a for-loop. We plot the unfiltered data in the columns on the left, and the filtered data in the columns on the right. I've used seewave::oscillo to view the results here and confirm that the data look filtered, but one could remove the calls to 'oscillo' if you don't care to plot the results.

```
# Read the first 10 ms of the data from all three channels
wav <- tuneR::readWave(wavFile,header = F,units = "seconds",from = 0,to=0.01)

# Placeholder for filtered data -- same size as original data
wavFiltData <- wav@.Data; 

op<-par(mfrow=c(3,2),mar=c(4.5,4,2,2))
for (i in 1:nchannel(wav)) {
  seewave::oscillo(wav,channel=i)
  wavFiltData[,i] <- seewave::bwfilter(wav,from=7400, to=7600,channel=i)
  # Edit: replaced wavFilt in line below with wavFiltData
  # to fix the error found by username_2
  seewave::oscillo(wavFiltData, f=wav@samp.rate, channel=i)
}

# Convert data back into a WaveMC format
wavFilt <- WaveMC(wavFiltData, samp.rate=wav@samp.rate, bit=wav@bit)

```

[![Plot showing original wav file on left, and filtered on right](https://i.sstatic.net/UmgHHoRE.png)](https://i.sstatic.net/UmgHHoRE.png)

> **Comments:**
> **username_2**: Q: I'm not good in R, but the second oscillo accesses wavFilt, which is only assigned to after the loop. Is that correct?  
> **username_1**: Yes, thank you this was indeed an error -- good catch. I have replaced wavFilt with wavFiltData, which I believe should now be correct.  

---

