Thursday 15 March 2012

loops - DJing with MATLAB (Low-Level I/O) -



loops - DJing with MATLAB (Low-Level I/O) -

alrighty everybody, it's time of week larn how weird things matlab. week it's djing. need figure out how create function output name of song length closest time left. instance, if i'm showing off djing skills , have 3:22 left, have pick song length closest time left (can shorter or longer). i'm given .txt file take from.

test case song1 = picksong('funeral.txt', '3:13') song1 => 'neighborhood #2 (laika)' file looks like: 1. neighborhood #1 (tunnels) - 4:48 2. neighborhood #2 (laika) - 3:33 3. une annee sans lumiere - 3:40 4. neighborhood #3 (power out) - 5:12 5. neighborhood #4 (7 kettles) - 4:49 6. crown of love - 4:42 7. wake - 5:39 8. republic of haiti - 4:07 9. rebellion (lies) - 5:10 10. in backseat - 6:21

i have of planned out, i'm having issue populating cell array. puts in lastly song, , changes -1 after loop runs. i've tried doing 3 different ways, lastly 1 beingness complex (and gross looking sorry). 1 time cell array it's proper form (as total song list , not -1) should in clear.

function[song] = picksong(file_name,time_remain) song_list = fopen(file_name, 'r'); %// opens file song_names = fgetl(song_list); %// retrieves lines, or song names here songs_in = ''; %// had cell array first, tried populate string time while ischar(songs) %// while loop pull out song names songs_in = {songs_in, songs}; songs = fgetl(song_list); if ischar(songs_in) %//how trying populate string song_info = []; while ~isempty(songs_in) [name, time] = strtok(songs_in); song_info = [song_info {name}]; end end end [songs, rest] = strtok(songs, '-'); [minutes, seconds] = strtok(songs, ':'); [minutes2, seconds2] = strtok(time_remain, ':') all_seconds = (minutes*60) + seconds; %// converting total time seconds all_seconds2 = (minutes2*60) + seconds2; song_times = all_seconds; time_remain = all_seconds2 time_remain = min(time_remain - song_times); fclose(file_name); end

please , give thanks help :)

a troublesome case:

song3 = picksong('resistance.txt', '3:57') song3 => 'exogenesis: symphony part 2 (cross-pollination)' 1. uprising - 5:02 2. resistance - 5:46 3. undisclosed desires - 3:56 4. united states of america of eurasia (+collateral damage) - 5:47 5. guiding lite - 4:13 6. unnatural selection - 6:54 7. mk ultra - 4:06 8. belong (+mon coeur s'ouvre ta voix) - 5:38 9. exogenesis: symphony part 1 (overture) - 4:18 10. exogenesis: symphony part 2 (cross-pollination) - 3:57 11. exogenesis: symphony part 3 (redemption) - 4:37

i'm going write reply using of have written, instead of suggesting different. though regexp powerful (and regular expressions), find advanced have learned far, let's scrap now.

this way, larn wrong code, how awesome of debugger (just kidding). have when reading in text file works. made selection in creating cell array store of strings.

i'm going borrow mrazzaman's logic in calculating time in seconds through strtok (awesome job btw).

in addition, i'm going alter logic bit makes sense me on how it. here's basic algorithm:

open file , read first line (song) did in code initialize cell array contains first song in text file until reach end of text file, read in entire line , add together cell array. you've noticed nail -1, don't have more songs read, break out of loop.

now have our songs in cell array, include track number, song , time each song, going create 2 more cell arrays. first 1 store times of songs strings, both minutes , seconds delimited :. next 1 contain names of songs themselves. now, go through each element in our cell array created step #3.

(a) populate first cell array, utilize strfind find all occurrences of - character occurs. 1 time find these occur, take last location of - occurs. utilize index our song string, , skip on 2 characters skip on - character , space character. extract of characters point until end of line extract our times.

(b) populate sec cell array, 1 time again utilize strfind, figure out spaces occur, , take index of first space happens. corresponds gap in between song number , track of song. using result of index (a), extract song title skipping 1 character index of first space index two characters before lastly - character song. because there space in between lastly word of song title before - character want remove space.

next, each song time in first cell array computed in step #4, utilize strtok have used , split string :. mrazzaman has used , i'm going borrow logic on computing total amount of seconds each time takes.

finally, figure out time closest time remaining. note need convert time remaining seconds did in step #5. mrazzaman has said, can utilize min function in matlab, , utilize second output of function. tells where in array minimum occurred. such, search minimum difference between time remaining , time elapsed each song. take note said don't care whether or not go on or under time elapsed. want closest time. in case, need take absolute value of time differences. let's had song took 3:59 , song 6:00, , time remaining 4:00. assuming there no song 4:00 long in track, want take song @ 3:59. however, if subtract time remaining longer track (6:00), negative difference, , min homecoming track... not song @ 3:59. why need take absolute value, disregard whether you're on or under time remaining.

once figure out song choose, homecoming song name gives minimum. create sure close file too!

without farther ado, here's code:

function [song] = picksong(file_name, time_remain) % // open file fid = fopen(file_name, 'r'); %// read first line song_name = fgetl(fid); %// initialize cell array song_list = {song_name}; %// read in song list , place %// each entry cell array while ischar(song_name) song_name = fgetl(fid); if song_name == -1 break; end song_list = [song_list {song_name}]; end %// now, each entry in our song list, find occurrences of '-' %// strfind, , take lastly index '-' occurs @ %// create sure skip on 2 spaces remove '-' , space song_times = cell(1,length(song_list)); song_names = cell(1,length(song_list)); idx = 1 : length(song_list) idxs = strfind(song_list{idx}, '-'); song_times{idx} = song_list{idx}(idxs(end)+2:end); idxs2 = strfind(song_list{idx}, ' '); %// figure out index of first space is, extract %// string starts 1 over, 2 places before %// lastly '-' character song_names{idx} = song_list{idx}(idxs2(1)+1 : idxs(end)-2); end %// have list of times each song. tokenize ':' %// separate minutes , times, calculate number of seconds %// logic borrowed mrazzaman song_seconds = zeros(1,length(song_list)); idx = 1 : length(song_list) [minute_str, second_str] = strtok(song_times{idx}, ':'); song_seconds(idx) = str2double(minute_str)*60 + str2double(second_str(2:end)); end %// now, calculate how much time remaining input [minute_str, second_str] = strtok(time_remain, ':'); seconds_remain = str2double(minute_str)*60 + str2double(second_str(2:end)); %// now, take song closest amount of time %// elapsed [~,song_to_choose] = min(abs(seconds_remain - song_seconds)); %// homecoming song want song = song_names{song_to_choose}; %// close file fclose(fid); end

with 2 illustration cases you've shown above, output get. i've taken liberty in creating own text files (awesome taste in) music:

>> song1 = picksong('funeral.txt', '3:13') song1 = neighborhood #2 (laika) >> song2 = picksong('resistance.txt', '3:57') song2 = exogenesis: symphony part 2 (cross-pollination)

matlab loops file-io text-files cell-array

No comments:

Post a Comment