Radio station discovery for ARM processors

Posted on

Some thoughts. These are ideas to play audio on a linux based platform, on a low powered device.

This is a daemon console audio player. It can play playlists

http://moc.daper.net/
https://github.com/jonsafari/mocp

How do you get the playlists generated so that it continues perpetually?

 

 

This can generate it’s own radio station based on scripting

liquidsoap.info/
https://github.com/savonet/liquidsoap

 

The Raspberry Pi devices need to have an RTC, otherwise they don’t know what time, or date they are each time they are turned on, unless they are connected to the internet.

This device solves that. http://www.uugear.com/product/wittypi2/

 

 

 

I saw this on a forum post. UK Sky News Audio feed: (I don’t know if it’s current)

Advertisements

StationPlaylist pushing to different ShoutCast 2 Streams.

Posted on Updated on

Well, it’s only taken much of the day, however it’s something that I finally got working, and it’s usually when you thought you’ve exhausted all options that you give up… but I had to try that one last time… And… I got it!

StationPlaylist is a great little piece of software for radio broadcasting. One of the things it has built in, is a web streamer, so that you can push the audio to a a ShoutCast or IceCast Stream.

This features work wonderfully and very simply if you only have one station. But, when you need to scale, things become less obvious – a lot less obvious.

In preparation for getting a multi-SPL install working and emulated on a VPS, or powerful VMs, I had to try this out just using the demo versions, and after much carry on, it seems to be working.

So, the idea is to get (at least) 2 versions of SPL to push to a linux ShoutCast 2 server. You can find multiple install instructions on how to do that, so I won’t even try to explain that part. I’ve written about it a couple of times in the past.
ShoutCast on a VPS
Shouter. Server

The problems with ShoutCast (apart from the fact that Winamp (NullSoft) or ShoutCast are doing a terrible job with their latest rendition of server software for the DYIer), and with SPL is that getting them to marry up with multiple instances is a real pain.

The secret to getting SPL to go to the correct server, with the correct SteamID is in the “Encoder Password” box.

Entering the following will connect you as User 3, a password of testing1, to stream Id 3.

3:testing1:#3

Screenshot 2018-04-02 22.13.32-edit

That’s not the only thing to configure. After putting bits together over the course of the last several hours and finding a couple of key pieces of information, it’s all come together.

It took me a long time to see this, but it’s mentioned in the SPL documentation under the Studio Help, Operation, Internet Streaming: under the heading “SPL Encoder Configuration”.

Note: SPL Encoder supports sending a single stream to a Shoutcast v1 or v2 server.  However, from Shoutcast Server v2.4.7, multiple streams may be sent to the same server by placing the stream ID in the Password field using this syntax…
password:#n   where n is the stream ID number.  eg. MyPass:#2

The other significant discovery was getting a configuration file working correctly too.

This is the sc_server_basic.conf file I ended up using for my testing:

 

; NOTE: for any relative paths specified are relative to
; sc_serv and not to where the conf file is being stored

; here we will setup where the log and other related files
; will be stored. make sure that these folders exist else
; sc_serv will throw an error and will close itself down.
; we will make the logs save to the sc_serv2 directory
logfile=logs/sc_serv.log
w3clog=logs/sc_w3c.log
banfile=control/sc_serv.ban
ripfile=control/sc_serv.rip

; for testing we will make the server only work locally
; (i.e. localhost / 127.0.0.1) though if this is left out
; or set to publicserver=always then we attempt to make a
; connection to the YP for listing - do not forget to add
; in a 'streamauthhash' value for any public streams made
;publicserver=never

; if you're wanting to use a different port to use for any
; connections then you can use this option e.g. to use 80
; otherwise port 8000 is used as the default to listen on.
;portbase=80

; password used by sc_trans or the Winamp dsp plug-in
; NOTE: remember to change this to something else
password=testing

; password used for accessing the administation pages
; NOTE: remember to change this to something else
adminpassword=changeme

; now we will specify the details of the stream we're going
; to serve which can be done as follows
;streamid=1
;streampath=/test.aac

; or

; it can be done like this which is how it needs to be done
; if you are going to provide multiple streams from sc_serv

password_1=testing1
streamid_1=1
streampath_1=/test1.mp3

password_2=testing2
streamid_2=2
streampath_2=/test2.mp3 
streampassword_2=testing1

password_3=testing
streamid_3=3
streampath_3=/test3.mp3 
streamadminpassword_3=testing 
streampassword_3=testing1

The significant things are the multi-stream configurations.

Screenshot 2018-04-02 22.46.51

In this image, there are only 3 separate streams shown as connected to my local server. 2 are using a demo copy of SPL, and the third (stream 2) is using the Shoucast DSP plugin in Winamp on a Windows 10 box (of which that plugin doesn’t work in SPL. If it did, I wouldn’t have spent all day figuring this out).

Screenshot 2018-04-02 22.17.51

That’s pretty much it. I hope it helps you, running multiple streams on the same server, through StationPlaylist, emulated in Wine using multiple instances with the help of PlayOnLinux.

The sky is the limit!

 

Troubles with sharing files on Windows 10

Posted on

It’s a bold statement, but after getting very frustrated last night, I thought I’d share a few revelations, and the troubles I had in sharing some files.

Recently, I spun up a couple of LinuxMint VMs. These typically have worked well, but there are areas where I’ve struggled, and at this point, I’m sharing about file sharing – from a Windows 10 box.

Here is the scenario. I want to share a folder that is inside the C:\Program Files (x86).

To be exact, it’s this one. I want to share this:

C:\Program Files (x86)\StationPlaylist\Playlist\

It works fine in MacOSX as a shared drive, but, when it comes to Linux, it’s a whole different ball game, and it just doesn’t want to play ball.

I have plenty of other shared folders on that Windows10 computer, and they all work fine. But, a folder buried in the “Program Files”, just doesn’t want to play ball.

I went through many versions of Samba config files, authentication methods, username/passwords, domain, problems with updates, SMB versions and a whole bunch of things. I even had to create a username and password in Windows, because LinuxMint didn’t want to just do an anonymous user login.

… in the end I gave up, extremely frustrated. Why does it have to be so difficult?? It works fine on the Macs… but not Linux.

I tried on last thing thing and made a fresh share on the Windows box, put it in “C:\Playlist” and shared it, and the share worked immediately.

Windows10 is a pain as it is, but throwing in Linux to the mix as well… it quickly turns to a nightmare.

Here is the connection procedure… The attempt to connecting to the share is from the “Program Files” share. That fails brilliantly. The second share, “C:\Playlist”, works spectacularly.

Screenshot 2018-04-02 15.28.22Screenshot 2018-04-02 15.28.46Screenshot 2018-04-02 15.28.59Screenshot 2018-04-02 15.29.23Screenshot 2018-04-02 15.29.30Screenshot 2018-04-02 15.29.39Screenshot 2018-04-02 15.29.46

Go figure… :/

 

VNC on Linux Mint – 3 steps!

Posted on Updated on

I’ve seen so many explanations of getting VNC to work well on Linux straight out of the box.

Well, they are all basically a pain to get working, with about 10 steps. It shouldn’t be so hard – especially when using Mint!

So, I was chuffed to find this guide which explains it very well! – in 3 steps! 😀

 

I hate ripping content like this, but in an effort to keep it available in case the site disappears, here it is:

 

https://helpdeskgeek.com/linux-tips/easiest-way-remotely-connect-linux-mint-os/

The Easiest Way to Remotely Connect to Linux Mint from Any OS

I have Linux Mint installed on a test machine at home that I use for playing around with Linux in general, but I use a Windows 10 machine as my main daily driver. I wanted a convenient way to connect to my Linux Mint machine from Windows or Mac without having to install all kind of packages, etc.

If you browse the Internet, you’ll see articles about installing XRDP, x11VNC, etc, etc. This all sounded a bit too complicated for me, especially since Linux Mint has built-in desktop sharing capabilities.

Warning: It’s worth noting that the method I’m describing below disables encryption for the remote connection.

For me, this is a non-issue since I am simply connecting to the Linux box from within my local network. If you need to have encryption enabled for the remote connection, I’ll be writing up another post soon on how to do that as it’s a bit more complicated.

Configure Desktop Sharing Settings

In Linux Mint, click on the menu button, Preferences and then Desktop Sharing. This will open the Desktop Sharing Preferences screen where you can enable other users to connect to the Linux system.

Under Sharing, go ahead and check the Allow other users to view your desktop and Allow other users to control your desktop boxes. Under Security, it’s probably a good idea to uncheck the You must confirm each access to this machine as that would require you to locally confirm the remote connection before it is accepted. If you’re giving someone else access to your machine, then it’s probably worth checking so that you can control when someone connects to your machine.

In order to prevent anyone from connecting to your machine, check the Require the user to enter this password box and type in a decently strong password. Click Close as we are done with this dialog.

Install dconf Editor

Next, we have to disable the encryption that is currently required by Vino, which is the package installed in Linux Mint by default. We have to install the dconf Editor, so that we can change the default settings.

Open Terminal and type in the following command:

sudo apt-get install dconf-editor

Once the package has been installed, click on the Linux Mint menu, then All Applications and scroll down till you see dconf Editor.

Open the editor and then navigate to orggnomedesktop remote-access.

In the right-hand pane, go ahead and uncheck the require-encryption box. Close the editor and then restart your Linux box. Once you are logged back in, we can try to connect.

Connect Using VNC Client

At this point, you can download your favorite VNC client for Windows and connect to the Linux box. In my case, I used the VNC Viewer program from RealVNC. You don’t have to sign up or pay for anything to use the viewer.

Type in the IP address for your Linux box and press Enter. Since there is no encryption, you’ll get a popup dialog telling you that your connection is not secure. Once you get past that message, you’ll have to enter the password you typed when we first setup desktop sharing settings on Linux Mint.

Hopefully, if all went well, you should now see the desktop for your Linux Mint machine.

As previously mentioned, this is a quick fix way to get into your Linux machine, but it is not secure. This means that all the data sent over the network is completely unencrypted, including passwords, etc. So, make sure no one can snoop on you if you plan to use this method. I’ll be posting another article soon on how to connect remotely to your Linux Mint box using encryption. If you have any questions, post a comment. Enjoy!

Raspberry Pi 3B FM Broadcasting… It can be done, but I want more.

Posted on Updated on

This is a discovery document and ramblings…  I’ve added to it all day and processed thoughts. I may adjust it and fix it, but, this is as it stands, as it took me about a day to compile.

 

 

This is going to be an interesting.

 

 

End Game:

Host a radio station on the Pi that just works. You turn it on and it starts transmitting a program.

In doing this…

Multiple ways:

Route Any audio that comes from the Pi to be transmitted via the FM TX.

Or

Read an M3u file and feed that to a audio player that pipes to the FM TX.

 

Hopefully to be able to use StationPlaylist Creator and Studio.

 

So far, only 1 version of a transmitter has succeeded.

Worked:

 

Only Plays WAVE files

https://www.youtube.com/watch?v=NdjQw6P0HLA
sudo ./fm_transmitter -f 91.3 -r star_wars.wav
https://github.com/somu1795/fm_transmitter

 

 

 

 

 

Failed:

 

http://www.instructables.com/id/Raspberry-Pi-PiFMPlay-Simplified-FM-Transmitter/

https://github.com/ChristopheJacquet/PiFmRds

https://github.com/Mikael-Jakhelln/PiFMPlay

 

Maybe this could work:

 

Haven’t Tried:

https://blog.morrolinux.it/raspberry-pi-fm-radio-transmitter-stereo-a2dp-bluetooth-rds/

 

 

https://github.com/somu1795/fm_transmitter

Broadcast from a usb microphone (see arecord manual page for config)

arecord -d0 -c2 -f S16_LE -r 22050 -twav -D copy | sudo ./fm_transmitter -f 103.3 -

Where it redirects a device to the FM TX…

Maybe I could set up a device/ALSA or something, and pipe that in to the TX?

 

 

Very Helpful, but didn’t work.
https://howtoraspberrypi.com/create-radio-transmitter-raspberry-pi/

 

 

Someone else wants the same thing:

Is there a way to redirect all audio to the FM transmitter? #18

 

The different Pins. We need GPIO 4, which is PIN 7

https://elinux.org/RPi_Low-level_peripherals#General_Purpose_Input.2FOutput_.28GPIO.29

 

 

Other information:

http://www.icrobotics.co.uk/wiki/index.php/Turning_the_Raspberry_Pi_Into_an_FM_Transmitter

 

Mostly idiots talking about “breaking the law”. At under 100mw, which this isn’t even close, it’s perfectly legal. But, it does contain some good RF stuff.

Easily Turn Your Raspberry Pi into an FM Transmitter

 

This is a kernel module for playback… Not sure on the status or if it works though.

 

https://github.com/spencerwhyte/RPIKMFMAD/issues/1

 

https://github.com/ChristopheJacquet/PiFmRds/issues/44

 

 

 

 

 

I think this is the key:

https://github.com/ChristopheJacquet/PiFmRds/issues/44

The easiest way to basicly play anything you want to, is by using audio loopdevices.
Simply load snd-aloop via modprobe (or just add it to /etc/modules), and you are ready to go.
use a terminal to start PiFm:
sudo arecord -fS16_LE -r 44100 -D hw:Loopback,1,0 -c 2 - | sudo ./pi_fm_rds -audio -

then you are free to play whatever you want with whatever program you want, as long as it allows you to specify the audio device you want to use to output to.
for example:
sudo aplay -D hw:Loopback,0,0 "FILE"

if you want to, you can even define the loopdevice as your standard output device, by changing the .asoundrc in your home directory to
# .asoundrc pcm.!default { type plug slave.pcm "hw:Loopback,0,0" }

That way you can even use VLC within X to transmit your audio.

 

 

https://unix.stackexchange.com/questions/310164/create-virtual-device-in-asoundrc-file

 

 

Trying:

This generates a new loopback device which wasn’t there before

sudo modprobe snd-aloop

Maybe Stationplaylist can actually play a file through this method… Not that it can see the loop-back audio driver?

 

sudo arecord -fS16_LE -r 44100 -D hw:Loopback,1,0 -c 2 - | sudo ./pi_fm_rds -audio -

 

Trying: https://github.com/F5OEO/PiFmRds

This is the latest version of the PiFmRds in Github.

Run this as well, Otherwise the build will fail when compiling it.

 

sudo apt-get install libsndfile1-dev

 

wget https://github.com/F5OEO/PiFmRds/archive/master.zip
unzip master.zip
cd PiFmRds-master/
cd src
make

Fails to build.

 

This builds:

git clone https://github.com/ChristopheJacquet/PiFmRds.git
cd PiFmRds/src
make clean
make

This will broadcast something on 107.5

sudo ./pi_fm_rds

This Demo will play a file in slow motion ( or correctly without the loopback I think)

sudo ./pi_fm_rds -audio sound.wav

 

Shows the Audio Devices.

arecord -L

 

This transmits, but it locks up the device after about 2 seconds.

sudo arecord -fS16_LE -r 44100 -D hw:Loopback,1,0 -c 2 - | sudo ./pi_fm_rds -audio -

https://linux.die.net/man/1/arecord

 

 

pi@raspberrypi:~/fm_transmitter-WAVE_Only $ sudo ./fm_transmitter -f 107.9 star_wars.wav

 

sudo arecord -fS16_LE -r 44100 -D hw:Loopback,1,0 -c 2 – | sudo ./fm_transmitter -f 107.9 -audio –

 

 

 

THIS WORKS!

Get the sourcecode from here:

https://github.com/markondej/fm_transmitter

 

 

sudo apt-get install make gcc g++
make

 

cd fm_transmitter-WAVE_Only/

sudo modprobe snd-aloop

sudo arecord -fS16_LE -r 44100 -D hw:Loopback,1,0 -c 2 – | sudo ./fm_transmitter -f 107.9 -audio –

 

Even at 22.5k it still stutters. A little less, but still noticeable.

sudo arecord -fS16_LE -r 22500 -D hw:Loopback,1,0 -c 2 – | sudo ./fm_transmitter -f 107.9 -audio –

 

 

pi@raspberrypi:~/fm_transmitter-WAVE_Only $ sudo modprobe snd-aloop
pi@raspberrypi:~/fm_transmitter-WAVE_Only $ sudo arecord -fS16_LE -r 44100 -D hw:Loopback,1,0 -c 2 – | sudo ./fm_transmitter -f 107.9 -audio –
Playing: STDIN
Recording WAVE ‘-‘ : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo

Right Click on the Speaker icon at the top. Set the Audio to LoopBack

Raspbian VLC should work with some Audio files and push play.

It should work!

 

CPU Stays at about 30%+

Audio also stutters slightly

 

install WineTricks and  Q4Wine

 

 

 

Currently I can’t get SPL to output to the Loopback – even though it says it is.

The WineCFG test outputs to the correct location, just not SSL.

 

Trying to set it up so it’s automatic a little.

Create the following files with a +777 permission and you should be good. Just change the location of the fm_transmitter file.

 

 start_radio.sh

sudo modprobe snd-aloop
#sudo arecord -fS16_LE -r 44100 -D hw:Loopback,1,0 -c 2 - | sudo /home/pi/fm_transmitter-WAVE_Only/fm_transmitter -f 107.9 -audio -
sudo arecord -Dhw:Loopback,1,0 -fS16_LE -r44100 -v -c 2 - | sudo /home/pi/fm_transmitter-WAVE_Only/fm_transmitter -f 107.9 -audio -

 

stop_radio.sh

sudo kill -9 $(pidof arecord)
sudo pkill -9 -f arecord
sudo kill -9 $(pidof fm_transmitter)
sudo killall -9 fm_transmitter
sudo pkill -9 -f fm_transmitter

 

 

Current conclusion: 20180317

I can now stream from any native program that is happy to follow the audio output rules of the system. VLC works fine, as does XMMS.

However, both programs have mild stutters about once a second for about .001 of a second. It’s minor, but it is noticeable. It’s like a CD with a minor glitch skip. Frustrating.

This isn’t there when “sudo ./fm_transmitter -f 91.3 -r star_wars.wav” is called. So, there is a buffering/hangup issue when using arecord to pipe the audio through, of which I need to investigate further and see if there are optimisations that can be made.

This current set up also using a consistent 30% of CPU resources in the X windows setup of the Noob version of the pi OS.

I suspect the problem could relate to the fact that it’s MP3s being upsampled to a WAVE @ 44.1khz stereo, captured, and then pushed out to the FM TX program. That’s a lot of data for a small processor.

 

 

 

Another possible option?

I could use the web streamer in SPL and capture that and feed it to the arecord. More investigation required, but I do recall someone mentioning that somewhere.

http://www.martinjhiggins.co.uk/shoutcast-streaming-from-a-raspberry-pi/

I’m trying IceCast2

 

sudo aptitude install icecast2

I wonder if I could use this as a template…

sox -t mp3 http://www.linuxvoice.com/episodes/lv_s02e01.mp3 -t wav -  | sudo ./pi_fm_rds -audio -

 

My Current Idea? – which could just put extra strain or processing on the device… but, it could do the opposite…?

Set SPL Output as NULL.

Set up the Streaming to the location newly created IceCast2 host.

So, go from SPL -> Icecast2 URL.

sox -t mp3 http://localhost/stream.mp3 -t wav - | sudo /home/pi/fm_transmitter-WAVE_Only/fm_transmitter -f 107.9 -audio -

 

After setting this up and SPL correctly connecting to the IceCast2 server, this doesn’t work because of the following error:

Playing: STDIN
sox WARN wav: Length in output .wav header will be wrong since can’t seek to fix it

 

It plays for about 3 seconds and then fades.

 

 

Next Stop… Asking the ExaGear guys. They are supporting wine, or similar. Time to see if they can assist…

 

Either that, or find a new player that read the m3u or pls files and have StationPlaylist Creator generate new files via CLI on a schedule.

The audio player/FM service could be stopped and started on a regular hourly basis so it keeps a rough time?

 

After letting it run overnight, I came to find that the radio broadcasting had stopped. This is probably because arecord has a time limit on it… Could be wrong.

Also, I’m thinking that the slight delay in the broadcast could be related to the speed of the card I’m using: Just a thought.

https://www.dwidigitalcameras.com.au/lexar-300x-32gb-45mb-s-high-performance-micro-sd-memory-card-with-sd-adapter.html

 

 

 

Observations and other research

ExaGear needed to have winbind install to run the demo version of StationPlaylist Creator

My result:

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
 600000

 

https://github.com/yeokm1/pi-radio

https://linux.die.net/man/1/arecord

https://alsa.opensrc.org/Jack_and_Loopback_device_as_Alsa-to-Jack_bridge#id02

XMMS2 – “Winamp”:
https://bytemyvdu.wordpress.com/2015/11/19/raspberry-pi-winamp/

https://makezine.com/projects/raspberry-pirate-radio/

After an original night trial without any audio radio tests to see how the pi could handle it, SPL Locked up overnight for some reason. Probably because it is a demo version.

When the fridge compressor pump kicked in to keep the fridge cooler, it must have caused a surge/brownout, as the pi rebooted, and the digital radio turned itself on… all the defaults.

php 7.1 and nginx not storing sessions

Posted on

Depending on your server settings, you may find every now and then and installing new modules, or program updates through yum, can break things.

Well, this happened to me.

I can’t explain what went wrong exactly, but after attempting to install the php mbstring extension, I had the whole thing go belly up.

After some frantic searching, I was able to solve the problem (eventually) by giving access once again to the nginx server, so it could store sessions.

Strangely enough, it was a permission error, where the location where php7.1 wanted to store it’s files had mysterious changed, or, the permission for that path had changed.

The solution was found in /var/opt/remi/php7X of all places.

Also, to help you find the problems, just look in your log files. It will often tell you what is wrong, or as to why it can’t do a certain task.

I thought I’d just let everyone know my quick thoughts.

Drive, Folder, Files Browsing VB.net 2107

Posted on Updated on

Finally, after searching the internet and finding nothing without modification I want to release some code, as it used be in the old VB5 and VB6 days.

I modified the code I’d found originally, and can’t remember which site did it, because most didn’t work at all. This however will get you the basics back using VB.NET.

(EDIT) Actually, this is the original code.  A HUGE THANKS!!! http://www.dreamincode.net/forums/topic/400525-treeview-drive-folder-and-file-explorer/

enjoy

 

Imports Microsoft.VisualBasic
Imports System.IO 'File Operations 
 

Public Class Form1

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
 AddSpecialAndStandardFolderImages()
 AddSpecialFolderRootNode(SpecialNodeFolders.Desktop)
 AddSpecialFolderRootNode(SpecialNodeFolders.MyDocuments)
 AddDriveRootNodes()
End Sub
 

 
Private Sub TV_Explorer_BeforeExpand(sender As Object, e As TreeViewCancelEventArgs) Handles Tv_Explorer.BeforeExpand
 Dim DrvIsReady As Boolean = (From d As DriveInfo In DriveInfo.GetDrives Where d.Name = e.Node.ImageKey Select d.IsReady).FirstOrDefault

If (e.Node.ImageKey <> "Desktop" AndAlso Not e.Node.ImageKey.Contains(":\")) OrElse DrvIsReady OrElse Directory.Exists(e.Node.ImageKey) Then
 e.Node.Nodes.Clear()
 AddChildNodes(e.Node, e.Node.Tag.ToString)

ElseIf e.Node.ImageKey = "Desktop" Then
 e.Node.Nodes.Clear()
 Dim PublicDesktopFolder As String = Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory)
 Dim CurrentUserDesktopFolder As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
 AddChildNodes(e.Node, CurrentUserDesktopFolder)
 AddChildNodes(e.Node, PublicDesktopFolder)

Else
 e.Cancel = True
 MessageBox.Show("The CD or DVD drive is empty.", "Drive Info...", MessageBoxButtons.OK, MessageBoxIcon.Information)
 End If
 End Sub

Private Sub TV_Explorer_AfterCollapse(sender As Object, e As TreeViewEventArgs) Handles Tv_Explorer.AfterCollapse
 e.Node.Nodes.Clear()
 e.Node.Nodes.Add("Empty")
 End Sub

Private Sub TV_Explorer_AfterSelect(sender As Object, e As TreeViewEventArgs) Handles Tv_Explorer.AfterSelect
 TxtBx_Path.Text = e.Node.Tag.ToString
 End Sub

Private Sub TV_Explorer_NodeMouseDoubleClick(sender As Object, e As TreeNodeMouseClickEventArgs) Handles Tv_Explorer.NodeMouseDoubleClick
 If e.Button = MouseButtons.Left AndAlso File.Exists(e.Node.Tag.ToString) Then
 Try
 Process.Start(e.Node.Tag.ToString)
 Catch ex As Exception
 MessageBox.Show(ex.Message, "Error...", MessageBoxButtons.OK, MessageBoxIcon.Error)
 End Try
 End If
 End Sub

Private Sub AddSpecialFolderRootNode(SpecialFolder As SpecialNodeFolders)
 Dim SpecialFolderPath As String = Environment.GetFolderPath(CType(SpecialFolder, Environment.SpecialFolder))
 Dim SpecialFolderName As String = Path.GetFileName(SpecialFolderPath)

AddImageToImgList(SpecialFolderPath, SpecialFolderName)

Dim DesktopNode As New TreeNode(SpecialFolderName)
 With DesktopNode
 .Tag = SpecialFolderPath
 .ImageKey = SpecialFolderName
 .SelectedImageKey = SpecialFolderName
 .Nodes.Add("Empty")
 End With

Tv_Explorer.Nodes.Add(DesktopNode)
 End Sub

Private Sub AddDriveRootNodes()
 For Each drv As DriveInfo In DriveInfo.GetDrives
 AddImageToImgList(drv.Name)
 Dim DriveNode As New TreeNode(drv.Name)
 With DriveNode
 .Tag = drv.Name
 .ImageKey = drv.Name
 .SelectedImageKey = drv.Name
 .Nodes.Add("Empty")
 End With
 Tv_Explorer.Nodes.Add(DriveNode)
 Next
 End Sub

Private Sub AddChildNodes(tn As TreeNode, DirPath As String)
 Dim DirInfo As New DirectoryInfo(DirPath)
 Try
 For Each di As DirectoryInfo In DirInfo.GetDirectories
 If Not (di.Attributes And FileAttributes.Hidden) = FileAttributes.Hidden Then
 Dim FolderNode As New TreeNode(di.Name)
 With FolderNode
 .Tag = di.FullName
 If Tv_ImgList.Images.Keys.Contains(di.FullName) Then
 .ImageKey = di.FullName
 .SelectedImageKey = di.FullName
 Else
 .ImageKey = "Folder"
 .SelectedImageKey = "Folder"
 End If
 .Nodes.Add("*Empty*")
 End With
 tn.Nodes.Add(FolderNode)
 End If
 Next

Dim files As String()
 Dim file As String
 File_ListView.Items.Clear()
 Try
 files = IO.Directory.GetFiles(DirPath) 'Your directory
 For Each file In files
 Dim FileInfo As New FileInfo(file)
 File_ListView.Items.Add(FileInfo.Name) 'adds all files in directory to listbox
 Next
 Catch ex As Exception
 MsgBox("You Can't Enter The Folder", MsgBoxStyle.Critical)
 End Try

Catch ex As Exception
 MessageBox.Show(ex.Message, "Error...", MessageBoxButtons.OK, MessageBoxIcon.Error)
 End Try
 End Sub

Private Sub AddSpecialAndStandardFolderImages()
 AddImageToImgList(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Folder")

Dim SpecialFolders As New List(Of Environment.SpecialFolder)
 With SpecialFolders
 .Add(Environment.SpecialFolder.Desktop)
 .Add(Environment.SpecialFolder.MyDocuments)
 .Add(Environment.SpecialFolder.Favorites)
 .Add(Environment.SpecialFolder.Recent)
 .Add(Environment.SpecialFolder.MyMusic)
 .Add(Environment.SpecialFolder.MyVideos)
 .Add(Environment.SpecialFolder.Fonts)
 .Add(Environment.SpecialFolder.History)
 .Add(Environment.SpecialFolder.MyPictures)
 .Add(Environment.SpecialFolder.UserProfile)
 End With

For Each sf As Environment.SpecialFolder In SpecialFolders
 AddImageToImgList(Environment.GetFolderPath(sf))
 Next
 End Sub

Private Function AddImageToImgList(FullPath As String, Optional SpecialImageKeyName As String = "") As String
 Dim ImgKey As String = If(SpecialImageKeyName = "", FullPath, SpecialImageKeyName)
 Dim LoadFromExt As Boolean = False

If ImgKey = FullPath AndAlso File.Exists(FullPath) Then
 Dim ext As String = Path.GetExtension(FullPath).ToLower
 If ext <> "" AndAlso ext <> ".exe" AndAlso ext <> ".lnk" AndAlso ext <> ".url" Then
 ImgKey = Path.GetExtension(FullPath).ToLower
 LoadFromExt = True
 End If
 End If

If Not Tv_ImgList.Images.Keys.Contains(ImgKey) Then
 'Tv_ImgList.Images.Add(ImgKey, Iconhelper.GetIconImage(If(LoadFromExt, ImgKey, FullPath), IconSizes.Large32x32))
 End If

Return ImgKey
 End Function

Private Enum SpecialNodeFolders As Integer
 Desktop = Environment.SpecialFolder.Desktop
 Favorites = Environment.SpecialFolder.Favorites
 History = Environment.SpecialFolder.History
 MyDocuments = Environment.SpecialFolder.MyDocuments
 MyMusic = Environment.SpecialFolder.MyMusic
 MyPictures = Environment.SpecialFolder.MyPictures
 MyVideos = Environment.SpecialFolder.MyVideos
 Recent = Environment.SpecialFolder.Recent
 UserProfile = Environment.SpecialFolder.UserProfile
 End Enum

End Class