Kogan 8GB MP4 - The Player That Came From Nowhere:
Aug 23, 2014 at 11:12 AM Post #76 of 1,681
  Just compared the Kogan to my ipod classic unamped, the Kogan more dynamic, bass hit harder & crisper. Very surprised.
I wonder though how long it will last quality wise for a $29 DAP? But sure as hell packs a punch.



I can agree with that Maquire - I've been tinkering around this evening with Shure SRH440. Kogan is clearly more detailed than my iPod Video tied to SMSL SAP-5. 
rolleyes.gif


No joke while they're both enjoyable, Kogan is obviously more detailed, higher in clarity and more dynamic.



 
Aug 23, 2014 at 11:10 PM Post #79 of 1,681
Yep, that's it . Please keep taunting us because it doesn't bother non-Aussies a single bit.
rolleyes.gif
Not at all.
ph34r.gif

 
Aug 23, 2014 at 11:52 PM Post #82 of 1,681
These are really amazing, I don't really want to admit how good they are, but let's just say with easy to drive IEMs they sound as good as a certain Fiio player from memory. Not as good as the DX50, but for $30 they are a bargain. 
 
Clarity and detail as mentioned before is awesome and these do a lot better than Sansas. Both the Clip+ and Zip sound like they are somewhat lacking compared to them. 
 
Soundstage and imaging is also very hard to fault for the price, the soundstage is pretty nice but not very big, larger than the Clip by a bit. Imaging is very impressive and the sense of space is shocking for the price. 
 
Kogan could have priced these at $100 and it would still be worth it. They even have a camera! The build is not great though and the battery is alright. I wished they would have made the player a bit wider and put a bigger battery in, but for $30 I'm not complaining. 
 
We just have to get these to the US somehow lol. It's disappointing how only Aussies can get this right now. I really hope Kogan does not jack up the price though. 
 
Aug 24, 2014 at 3:34 AM Post #84 of 1,681
Here's a playlist generation powershell script.
the basic usage is powershell fullpathto\writeMp4Playlist.ps1

you may need to run powershell and then do 'set-executionpolicy bypass -Scope:CurrentUser' and then fullpathto\writeMp4Playlist.ps1


you will need to edit the path to the playlist folder and to the music folders to correspond to the player ones.
$rootFolder='j:\music'.toupper()
$plOutputFile='i:\Playlist\MSCLST.0'

The script will then generate a playlist file from that folder and all of its subfolders for all the filetypes specified in
$filter=@("*.flac","*.mp3","*.ape")

you can also specify the second-5th playlist as the output. (e.g. MSCLST.1)


Currently I noticed the following limitations:
a) it won't do international filenames (powershell returns them in utf-8. to convert them to char I need to know the end intl encoding the player uses, plus the conversion script inside seems to produce ?? bytes instead of intl ones. anyway). I suggest renaming those files to transliterate.
b) if you go over some sort of file # limit, the player writes garbage to all files except for ACTMMLIB.PLS in playerdrive:\playlists
i:\playlist\nowplay.0,1,2 removed as it writes trash output there. (probably a buffer overflow if you exceed the max # of songs it thinks you should have). Just delete those nowplay files.
c) while the my list file # is identical to the specified, when you look at the current playing it's about 20-50 less. I'm not sure why.

usually if it works it makes a file called acciplay.0 a copy of the msclst.x you picked.

I probably suggest removing dirplay.0
msctag.0
nowplay.0
nowplay.1
nowplay.2

before running the script.



the best use is probably make 1-5 playlists 1000 files each. you can control those parameters with
$toSkip
$limitSongs

and by varying the playerdrive:\playlists\MSCLST.0-4

I can tell you mine was ok with 2000 songs, but definitely not ok with 2500, or 2500+ (not sure at what point it starts writing random cr!p to files but it may well have to do with # of records)
From what I can tell the random cr!p writing is limited to the internal storage playlist folder so you won't trash your sd. just cleanup i:\playlist\ if any problems (player usually deletes offending items on reboot anyway)
Code:
#Kogan mp4 playlist generator by svyr@headfi 
#v0.11 @ 23/08/2014 - initial release
#v0.12 @ 24/08/2014 - fixed file part length bug where it was set to a static value, fixed the pl num byte (hex not dec)

$rootFolder='j:\music'.toupper()
$plOutputFile='i:\Playlist\MSCLST.0'
$playListNum=[int]::parse($plOutputFile[$plOutputFile.Length-1])
$playListNumByte=$playListNum*32
$filter=@("*.flac","*.mp3","*.ape")
$foldCont = Get-ChildItem $rootFolder -Recurse -Include $filter

$toSkip=0
$limitSongs=0


###short filename code from http://www.tellingmachine.com/post/Converting-file-names-to-the-DOS-83-format-using-PowerShell.aspx
$DebugPreference = "continue"

function Get-Script-Directory
{
 $scriptInvocation = (Get-Variable MyInvocation -Scope 1).Value
 return Split-Path $scriptInvocation.MyCommand.Path
}

 
function Load-FileSystemHelper()
{
 $Code =
@"
using System;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using System.Globalization;
 
public class FileSystemHelper
{
 [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
 private static extern int GetShortPathName(
 [MarshalAs(UnmanagedType.LPTStr)] string path,
 [MarshalAs(UnmanagedType.LPTStr)] StringBuilder shortPath,
 int shortPathLength);
 
 [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
 [return: MarshalAs(UnmanagedType.U4)]
 private static extern int GetLongPathName(
 [MarshalAs(UnmanagedType.LPTStr)]
 string lpszShortPath,
 [MarshalAs(UnmanagedType.LPTStr)]
 StringBuilder lpszLongPath,
 [MarshalAs(UnmanagedType.U4)]
 int cchBuffer);
 
 public static string GetShortPathName(string path)
 {
 StringBuilder shortPath = new StringBuilder(500);
 if (0 == GetShortPathName(path, shortPath, shortPath.Capacity))
 {
 if (Marshal.GetLastWin32Error() == 2)
 {
 throw new Exception("File does not exist!");
 }
 else
 {
 throw new Exception("GetLastError returned: " + Marshal.GetLastWin32Error());
 }
 }
 return shortPath.ToString();
 }
 
 
 public static string GetLongPathName(string shortPath)
 {
 if (String.IsNullOrEmpty(shortPath))
 {
 return shortPath;
 }
 
 StringBuilder builder = new StringBuilder(255);
 int result = GetLongPathName(shortPath, builder, builder.Capacity);
 if (result > 0 && result < builder.Capacity)
 {
 return builder.ToString(0, result);
 }
 else
 {
 if (result > 0)
 {
 builder = new StringBuilder(result);
 result = GetLongPathName(shortPath, builder, builder.Capacity);
 return builder.ToString(0, result);
 }
 else
 {
 throw new FileNotFoundException(
 string.Format(
 CultureInfo.CurrentCulture,
 null,
 shortPath),
 shortPath);
 }
 }
 }
}
"@
 
 Add-Type -TypeDefinition $Code
}
 
 
function Get-DOSPathFromLongName([string] $Path)
{
 Load-FileSystemHelper
 $DOSPath = [FileSystemHelper]::GetShortPathName($Path)
 Write-Debug $DOSPath
 return $DOSPath
}
 
function Get-LongNameFromDOSPath([string] $Path)
{
 Load-FileSystemHelper
 $LongPath = [FileSystemHelper]::GetLongPathName($Path)
 Write-Debug $LongPath
 return $LongPath
}
 
#$DOSPath = Get-DOSPathFromLongName -Path "C:\Program Files (x86)\"
### end of short filename code from http://www.tellingmachine.com/post/Converting-file-names-to-the-DOS-83-format-using-PowerShell.aspx */

### byte array function from http://cyber-defense.sans.org/blog/2010/02/11/powershell-byte-array-hex-convert */
function Convert-ByteArrayToHexString
{
################################################################
#.Synopsis
# Returns a hex representation of a System.Byte[] array as
# one or more strings. Hex format can be changed.
#.Parameter ByteArray
# System.Byte[] array of bytes to put into the file. If you
# pipe this array in, you must pipe the [Ref] to the array.
# Also accepts a single Byte object instead of Byte[].
#.Parameter Width
# Number of hex characters per line of output.
#.Parameter Delimiter
# How each pair of hex characters (each byte of input) will be
# delimited from the next pair in the output. The default
# looks like "0x41,0xFF,0xB9" but you could specify "x" if
# you want the output like "x41xFFxB9" instead. You do
# not have to worry about an extra comma, semicolon, colon
# or tab appearing before each line of output. The default
# value is ",0x".
#.Parameter Prepend
# An optional string you can prepend to each line of hex
# output, perhaps like '$x += ' to paste into another
# script, hence the single quotes.
#.Parameter AddQuotes
# An switch which will enclose each line in double-quotes.
#.Example
# [Byte[]] $x = 0x41,0x42,0x43,0x44
# Convert-ByteArrayToHexString $x
#
# 0x41,0x42,0x43,0x44
#.Example
# [Byte[]] $x = 0x41,0x42,0x43,0x44
# Convert-ByteArrayToHexString $x -width 2 -delimiter "x" -addquotes
#
# "x41x42"
# "x43x44"
################################################################
 [CmdletBinding()] Param (
 [Parameter(Mandatory = $True, ValueFromPipeline = $True)] [System.Byte[]] $ByteArray,
 [Parameter()] [Int] $Width = 10,
 [Parameter()] [String] $Delimiter = ",0x",
 [Parameter()] [String] $Prepend = "",
 [Parameter()] [Switch] $AddQuotes )

if ($Width -lt 1) { $Width = 1 }
 if ($ByteArray.Length -eq 0) { Return }
 $FirstDelimiter = $Delimiter -Replace "^[,\:t]",""
 $From = 0
 $To = $Width - 1
 Do
 {
 $String = [System.BitConverter]::ToString($ByteArray[$From..$To])
 $String = $FirstDelimiter + ($String -replace "-",$Delimiter)
 if ($AddQuotes) { $String = '"' + $String + '"' }
 if ($Prepend -ne "") { $String = $Prepend + $String }
 $String
 $From += $Width
 $To += $Width
 } While ($From -lt $ByteArray.Length)
}

### end of byte array function from http://cyber-defense.sans.org/blog/2010/02/11/powershell-byte-array-hex-convert */ 


#from https://xaegr.wordpress.com/category/scripting/page/42/
function ConvertTo-Encoding ([string]$From, [string]$To){
 Begin{
 $encFrom = [System.Text.Encoding]::GetEncoding($from)
 $encTo = [System.Text.Encoding]::GetEncoding($to)
 }
 Process{
 $bytes = $encTo.GetBytes($_)
 $bytes = [System.Text.Encoding]::Convert($encFrom, $encTo, $bytes)
 $encTo.GetString($bytes)
 }
}

$allRecords = new-object Byte[] 1

$k=0
foreach($afile in $foldcont){
 if($afile.Attributes -ne "Directory"){
 if($k -lt $toSkip){
 Write-Debug ("Skipping #" + $k + " " + $afile.fullname)
 $k++;
 
 continue;
 }
 Write-Debug ("Adding #" + $k + " " + $afile.fullname)
 $shortFn=(Get-DOSPathFromLongName($afile.fullname.ToUpper()))
 $shortFn=$shortFn.Replace($rootFolder.Substring(0,3),'D:\')
 $shortFnLen=$shortFn.length
 $lastSlashInShortFn=$shortFn.LastIndexOf('\')+1
 $fileNamePart=$shortFn.Substring($lastSlashInShortFn,($shortFnLen-$lastSlashInShortFn))
 $filePartLength=$fileNamePart.length
 $recLen=16+$shortFnLen+1;
 $record= New-Object Byte[] $recLen
 $record[0]=[Byte]$reclen
 $record[2]=$playListNumByte
 $record[3]=0xb0
 $record[4]=$lastSlashInShortFn
 $record[8]=$filePartLength
 $record[$recLen-1]=0x0a
 $offset=16;
 for ($i=0; $i -lt $shortFnLen; $i++){
 $record[$i+$offset]=$shortFn[$i]
 }
 
 $allRecords +=$record

 $k++
 if($limitSongs -gt 0 -and $k -eq ($toSkip+$limitSongs)){
 break;
 }
 }
}


$allRecords2= new-object Byte[] ($allRecords.Length-1)

for ($i=1; $i -lt $allRecords.Length; $i++){
 $allRecords2[$i-1]=$allRecords[$i]
}
 



function Get-Script-Directory
{
 $scriptInvocation = (Get-Variable MyInvocation -Scope 1).Value
 return Split-Path $scriptInvocation.MyCommand.Path
}

function Get-Script-Directory
{
 $scriptInvocation = (Get-Variable MyInvocation -Scope 1).Value
 return Split-Path $scriptInvocation.MyCommand.Path
}


$tempFileName=[environment]::GetEnvironmentVariable('TEMP') + "\temppl.0"
if([System.IO.File]::Exists($tempFileName)){
 [System.IO.File]::Delete($tempFileName)
}
Add-Content -Path $tempFileName -value $allRecords2 -encoding byte
 
move $tempFileName $plOutputFile -force
#
#looking at the format of G:\Playlist\msclst.0 
#so far it looks like you get a record for each file like this :

#00 ?? record size byte from here until the 0a (inclusive). This is basically 16 bytes + dos 8.3 filename length + 0a 
#01 00
#02 ?? (00 for pl 0 - msclst.0, 20 for pl1, 40 for pl2, 60 for pl3)
#03 b0
#04 ?? length of the 8.3 dos filename till last slash (including the last slash) e.g. (D:\MUSIC\MISC\BRUNOM~1\)05THEL~1.FLA = 0x17 (23) or (D:\MUSIC\MISC\LS\)05MOON~1.FLA = 0x11 (17)
#05 00 (3 of the 0 bytes)
#06 00 
#07 00
#08 ?? dos file name part length (e.g. ...\(tra~1.fla) excl the slash 
#09 00 (7 of the 0 bytes)
#10 00 
#11 00 
#12 00 
#13 00 
#14 00 
#15 00
#16 d:\dosfilename incl path (ascii)
#last rec char 0a
 
Aug 24, 2014 at 1:54 PM Post #90 of 1,681
well I did find a smaller 8 gb card clip style player by Kogan available outside AUS. You even get a top with it
wink_face.gif

 But as usual shipping costs the same as the player.
So there's hope yet
 

Users who are viewing this thread

Back
Top